advent of code 2023 day 8
This commit is contained in:
parent
5b300c65fb
commit
c3684c23b1
|
@ -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?
|
||||
|
|
@ -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++
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
})
|
Loading…
Reference in New Issue