Posted in:

I did it! I got my 25 stars on Advent of Code for this year, with all my solutions in JavaScript. With today being Christmas day, I was hoping it would be a quick one and thankfully it was relatively kind. Basically, the input described a simple state machine, with the rules for what to do in each state as you filled up a “tape” with values.

I opted to speed up things a bit by not parsing the input directly and hard-coding the values from my input. I needed the start state, and number of steps as well as a bunch of rules governing what should happen in each of the six states:

let state = 'A'
const steps = 12481997
let cursor = 0
let tape = {}

let rules =
    {'A': [1,1,'B',0,-1,'C'],
     'B': [1,-1,'A',1,1,'D'],
     'C': [0,-1,'B',0,-1,'E'],
     'D': [1,1,'A',0,1,'B'],
     'E': [1,-1,'F',1,-1,'C'],
     'F': [1,1,'D',1,1,'A']}

With this in place, I just iterate through for the number of steps, and each step we update the contents of the “tape” at the current “cursor” position, as well as move to a new state. The decision of what to do is based on the value of the current position in the tape. In previous days I’ve used the ES6 Map object to store the contents of the tape, but here I’m using a regular JavaScript object as it allows a slightly simplified syntax in our loop, using destructuring arrays to assign three values each time through the loop:

for(let step = 0; step < steps; step++) {
    let rule = rules[state];
    [tape[cursor],cursor,state] = (tape[cursor]) ? 
        [rule[3],cursor+rule[4],rule[5]] :
        [rule[0],cursor+rule[1],rule[2]];
}

Finally to get the puzzle input we need to count how many entries in the tape have the value 1. JavaScript objects are not “iterables” so we need to use the for…in syntax rather than for…of:

let checksum = 0
for(let p in tape) {
    if (tape[p] === 1) checksum++;
}
return checksum;

So I managed to solve today’s puzzle relatively quickly, although sadly this year I wasn’t able to make the leaderboard on any of the 25 days. The leaderboard (top 100) is usually full by about 6:00am UK time, and I typically started solving each day’s puzzle at 7:30.

I felt a bit bad about not parsing the input for today’s puzzle, so I took the opportunity to refactor during some down-time in the afternoon to use regexes to construct the rules from the input file:

let state = input[0].match(/Begin in state (.)\./)[1]
const steps = Number(input[1].match(/after (\d+) steps/)[1])
let cursor = 0, tape = {}, rules = {}
const parseState = s => s.match(/state (.)/)[1] 
const parseVal = s => Number(s.match(/the value (\d)\./)[1])
const parseDir = s => s.match(/to the right/) ? 1 : -1 
for(let b of batch(skip(input,2),9)) { // nb blank input lines already stripped
    rules[parseState(b[0])] = [parseVal(b[2]),parseDir(b[3]),parseState(b[4]),
                               parseVal(b[6]),parseDir(b[7]),parseState(b[8])]
}

It’s been a great learning experience doing this year’s Advent of Code challenges in node.js with ES6, and I highly recommend doing a daily coding challenge like this if you want to pick up a new language. My code for all the days is available on GitHub and I’d love to hear any feedback on how I can improve my solutions.

All that remains is for me to wish you a very Happy Christmas! I hope you are able to enjoy some relaxing time with friends and family during the holidays, and that you’ve learned something useful from these blogs.