advent of code 2023 day 8

This commit is contained in:
Wouter Groeneveld 2023-12-08 14:13:22 +01:00
parent 5b300c65fb
commit c3684c23b1
3 changed files with 89 additions and 0 deletions

34
2023/08/assignment.md Normal file
View File

@ -0,0 +1,34 @@
# --- Day 8: Haunted Wasteland ---
You're still riding a camel across Desert Island when you spot a sandstorm quickly approaching. When you turn to warn the Elf, she disappears before your eyes! To be fair, she had just finished warning you about ghosts a few minutes ago.
One of the camel's pouches is labeled "maps" - sure enough, it's full of documents (your puzzle input) about how to navigate the desert. At least, you're pretty sure that's what they are; one of the documents contains a list of left/right instructions, and the rest of the documents seem to describe some kind of network of labeled nodes.
It seems like you're meant to use the left/right instructions to navigate the network. Perhaps if you have the camel follow the same instructions, you can escape the haunted wasteland!
After examining the maps for a bit, two nodes stick out: AAA and ZZZ. You feel like AAA is where you are now, and you have to follow the left/right instructions until you reach ZZZ.
This format defines each node of the network individually. For example:
RL
AAA = (BBB, CCC)
BBB = (DDD, EEE)
CCC = (ZZZ, GGG)
DDD = (DDD, DDD)
EEE = (EEE, EEE)
GGG = (GGG, GGG)
ZZZ = (ZZZ, ZZZ)
Starting with AAA, you need to look up the next element based on the next left/right instruction in your input. In this example, start with AAA and go right (R) by choosing the right element of AAA, CCC. Then, L means to choose the left element of CCC, ZZZ. By following the left/right instructions, you reach ZZZ in 2 steps.
Of course, you might not find ZZZ right away. If you run out of left/right instructions, repeat the whole sequence of instructions as necessary: RL really means RLRLRLRLRLRLRLRL... and so on. For example, here is a situation that takes 6 steps to reach ZZZ:
LLR
AAA = (BBB, BBB)
BBB = (AAA, ZZZ)
ZZZ = (ZZZ, ZZZ)
Starting at AAA, follow the left/right instructions. How many steps are required to reach ZZZ?

23
2023/08/impl.js Normal file
View File

@ -0,0 +1,23 @@
module.exports.solve = function(input) {
const [instructionLine, nodeLines] = input.split('\n\n')
const instructions = instructionLine.split('').map(s => s === 'R' ? 1 : 0)
const map = {} // this could be a reduce()?
const nodes = nodeLines.split('\n').forEach(line => {
// e.g. AAA = (BBB, CCC)
const [pos, _, left, right] = line.replace(/[\(]?[\)]?[=]?[,]?/g, "").split(' ')
map[pos] = [left, right]
})
let curr = 'AAA'
let i = 0
// I'm sure recursion is more elegant here, but my playtime for today is up
while(true) {
const loc = map[curr]
const direction = instructions[i % instructions.length]
curr = loc[direction]
if(curr === 'ZZZ')
return i + 1
i++
}
}

32
2023/08/test.js Normal file
View File

@ -0,0 +1,32 @@
const test = require('node:test')
const assert = require('node:assert').strict;
const { readFileSync } = require('fs')
const { solve } = require('./impl.js')
test('Amount of steps is 2 since ZZZ is immediately found', (t) => {
const input = `RL
AAA = (BBB, CCC)
BBB = (DDD, EEE)
CCC = (ZZZ, GGG)
DDD = (DDD, DDD)
EEE = (EEE, EEE)
GGG = (GGG, GGG)
ZZZ = (ZZZ, ZZZ)`
const out = solve(input)
assert.equal(out, 2)
})
test('Amount of steps is 6 because LR instructions need to be repeated', (t) => {
const input = `LLR
AAA = (BBB, BBB)
BBB = (AAA, ZZZ)
ZZZ = (ZZZ, ZZZ)`
const out = solve(input)
assert.equal(out, 6)
})