Advent of Code: Day 3

I’m enjoying this! I’ve been using Zed Code Editor for this, because it doesn’t have any kind of AI or auto-complete, so I’m forced to remember everything. It’s been a fun lil challenge, probably the only one I’ll give myself this month, outside of you know… completing them.

Today’s challenge was a bit more complex than the previous two. We had to parse a string of instructions, and extract some information from them. The instructions were encoded in memory, but poorly. We had to extract the total of all “mul(x, y)” instructions. Step two added an additional instruction: anything between don't() and do().

I’m never sure if I’m doing it right when I break out a regex, but regexr is always there to help me out.

You’ll see in my comments that I tried to get ahead of myself, assuming that there would be additional math functions to implement. I was wrong, and it’s a great example of trying to generalize and solve problems that don’t exist yet. Advent of Code is an opportunity to not do that .

The second part of the challenge was the parseInstructions function, where I got a lot more hacky. I split the instructions on the don't() and do() and then just toggled a boolean to determine if the instructions were enabled or not. I’m sure there’s a better way to do this, but this is the point where I was ready to finish. You’ll notice my comments are a bit less teach-y and a bit more stream of consciousness

Here is todays code:

import {getInstructionContent} from './input';

// The elves (? did I make that up) have a computer with instructions encoded in memory, but poorly
// 1️⃣ We have to go through the instructions and get out any "mul(x, y)", however garbled and get the total
// 2️⃣ Ignore anything after `don't()` until the next `do()` and get the total

function followInstructions(instructions: string): Array<string> {
  const regex = /[a-zA-Z_]*mul\((\d+),(\d+)\)/g;
  const matches = [];
  let match;

  while ((match = regex.exec(instructions)) !== null) {
    // I kept the mul(a, b) format because I ASSUMED that the second task would be
    // to implement other math functions. i was wrong 😭 but doesn't matter
    // at least not enough to go back and fix
    matches.push(`mul(${match[1]},${match[2]})`);
  }
  return matches;
}

function parseInstructions(instructions: string): string {
  let isEnabled = true; // enabled by default
  let resultingCode = '';

  // use a regex to match "don't()" and "do()"
  const parts = instructions.split(/(don't\(\)|do\(\))/);

  for (const part of parts) {
    if (part === "don't()") {
      isEnabled = false; // disable the machine
    } else if (part === 'do()') {
      isEnabled = true; // enable the machine
    } else if (isEnabled) {
      resultingCode += part; // append the enabled instructions
    }
  }

  return resultingCode;
}

function processMultiplyers(instructions: string): Number {
  // Get array of valid instructions
  const parsedInstructions = parseInstructions(instructions);
  const validInstructions = followInstructions(parsedInstructions);

  // Process each instruction and sum the results
  const sum = validInstructions.reduce((total, instruction) => {
    console.log(`Valid Instruction: ${instruction}`);
    // Extract numbers from mul(x,y)
    const numbers = instruction.match(/\d+/g);
    // Some safety rails if parsing didn't go 100%
    if (numbers && numbers.length === 2) {
      // Convert to numbers and multiply
      const result = parseInt(numbers[0]) * parseInt(numbers[1]);
      return total + result;
    } else {
      console.log('ERROR');
    }
    return total;
  }, 0);

  return sum;
}

// starting today, making a boot function day*(), that'll run the stuff
// i just had out in the open before. uncivilized.
function day3() {
  const instructions = getInstructionContent();
  const total = processMultiplyers(instructions);
  console.log(`And the added together multiplyer is ${total}`);
}

day3();