Public
Edited
Dec 8, 2023
Insert cell
Insert cell
Insert cell
function parse(input) {
const g = new Graph();
const [instr, map] = input.split("\n\n");

for (const line of map.split("\n")) {
const [_, a, b, c] = line.match(/(\w+)\s*=\s*\((\w+),\s*(\w+)\)/);
g.addEdge(a, b);
g.addEdge(a, c);
}
return { dirs: instr.split(""), graph: g };
}
Insert cell
Insert cell
function stepsToExit(instrs) {
let steps = 0;
let current = "AAA";
while (current !== "ZZZ") {
const instr = instrs.dirs[steps % instrs.dirs.length];
if (instr === "L") {
current = instrs.graph.adjacent(current)[0];
} else {
current = instrs.graph.adjacent(current)[1];
}
steps++;
}
return steps;
}
Insert cell
function part1(input) {
return stepsToExit(parse(input));
}
Insert cell
Insert cell
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

Insert cell
Insert cell
Insert cell
function getPeriods(instrs) {
const currents = instrs.graph.nodes().filter((n) => n.endsWith("A"));
let steps = 0;
const periods = new Map();

while (periods.size < currents.length) {
const i = steps % instrs.dirs.length;
const next = instrs.dirs[i] === "L" ? 0 : 1;

currents.forEach((current, j) => {
currents[j] = instrs.graph.adjacent(current)[next];
if (currents[j].endsWith("Z") && !periods.has(j)) {
periods.set(j, steps + 1);
}
});
steps++;
}
return [...periods.values()];
}
Insert cell
Insert cell
function part2(input) {
return AOC.lowestCommonMultiple(...getPeriods(parse(input)));
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more