loading...

re: Advent of Code 2019 Solution Megathread - Day 9: Sensor Boost VIEW POST

FULL DISCUSSION
 

So, we're going to work with Intcodes every other day? 😩

The worst part is that, since we're reserving two digit for the opcodes, I expect we're going to work with them again in the future (even though it says "You now have a complete Intcode computer.")

Moreover, the problem forgot to mention that when we write back to the memory, it could be done in relative mode too and not just position mode. Thanks 🤦‍♂️

But anyway... JavaScript with generators blah blah. I lost quite some time trying to understand why my solution didn't work... Until I realized I was passing the input values incorrectly 😵 I have none but myself to blame there...

Only new thing: the use of JavaScript's BigInt. Hooray for ES2020!

Solution for both parts:

const parameterCount = { 1: 3, 2: 3, 3: 1, 4: 1, 5: 2, 6: 2, 7: 3, 8: 3, 9: 1, 99: 0 };
const codes = input.split(',').map(BigInt);

function* createProgramInstance(localCodes, ...stack) {
  let instructionPointer = 0;
  let relativeBase = 0;
  function* getInstructions() {
    while (instructionPointer < localCodes.length) {
      const instruction = Number(localCodes[instructionPointer]);
      const opcode = instruction % 100;
      const modes = Array.from({ length: 3 }, (_, index) => Math.floor(instruction / 10 ** (index + 2) % 10));
      const paramCount = parameterCount[opcode];
      const params = localCodes.slice(instructionPointer + 1, instructionPointer + paramCount + 1);
      instructionPointer += paramCount + 1;
      yield { opcode, modes, params };
    }
  }

  function execute({ opcode, modes, params }) {
    function getAddress(index) {
      return (modes[index] === 2 ? relativeBase : 0) + Number(params[index]);
    }
    function getValue(index) {
      const value = modes[index] === 1 ? params[index] : localCodes[getAddress(index)];
      return typeof value === 'bigint' ? value : 0n;
    }

    switch (opcode) {
      case 1:
        localCodes[getAddress(2)] = getValue(0) + getValue(1);
        break;
      case 2:
        localCodes[getAddress(2)] = getValue(0) * getValue(1);
        break;
      case 3:
        localCodes[getAddress(0)] = stack.shift();
        break;
      case 4:
        return getValue(0);
      case 5:
        if (getValue(0)) {
          instructionPointer = Number(getValue(1));
        }
        break;
      case 6:
        if (getValue(0) === 0n) {
          instructionPointer = Number(getValue(1));
        }
        break;
      case 7:
        localCodes[getAddress(2)] = BigInt(getValue(0) < getValue(1));
        break;
      case 8:
        localCodes[getAddress(2)] = BigInt(getValue(0) === getValue(1));
        break;
      case 9:
        relativeBase += Number(getValue(0));
        break;
    }
  }

  for (const instruction of getInstructions()) {
    if (instruction.opcode === 99) {
      return;
    }
    const output = execute(instruction);
    if (typeof output === 'bigint') {
      yield output;
    }
  }
}

for (const part of [1n, 2n]) {
  const program = createProgramInstance(codes, part);
  console.log(`# Part ${part}`);
  for (const value of program) {
    console.log(String(value));
  }
}

Running times:

  1. ~2.5 ms
  2. ~370 ms

Hardware: MacBook Pro mid-2015

As usual, my text and input can be found on my repo.

BTW, I'm dead last in the leaderboards among those who completed all 9 days 😂 Jon, you're ahead of me without today!

 

I believe the two digits are just there because of opcode 99 :)

 

And that would make ten opcodes so far, right.

Well, let's hope we won't have to implement more! 😄

After all we already have basic arithmetic, I/O, conditional jumps, comparisons and pointer manipulation... What else do we need for a basic processor?

We're in uncharted waters! I think this is first year we've had so much refactoring/reuse work to do. (Definitely the earliest)

It's been pretty frustrating going, but getting things to work has been satisfying as heck.

 

the problem forgot to mention that when we write back to the memory, it could be done in relative mode too and not just position mode.

this burned me, i sat there for 30 minutes trying to figure out what i was doing wrong

Code of Conduct Report abuse