DEV Community

Discussion on: Advent of Code 2019 Solution Megathread - Day 9: Sensor Boost

Collapse
 
maxart2501 profile image
Massimo Artizzu • Edited

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!

Collapse
 
johnnyjayjay profile image
Johnny

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

Collapse
 
maxart2501 profile image
Massimo Artizzu

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?

Thread Thread
 
jbristow profile image
Jon Bristow • Edited

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.

Collapse
 
mustafahaddara profile image
Mustafa Haddara

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