import fs from "fs"; function gcd(a: number, b: number) { return !b ? a : gcd(b, a % b); } function lcm(a: number, b: number) { return (a * b) / gcd(a, b); } const [directions, _, ...lines] = fs .readFileSync("./input.txt") .toString() .split("\n") .slice(0, -1); const nodes = lines .map((line) => { const match = line.match(/(...) = \((...), (...)\)/); if (!match) throw new Error("Could not match"); return { node: match[1], left: match[2], right: match[3], }; }) .map((node, index, nodes) => ({ name: node.node, node: index, left: nodes.findIndex((n) => n.node === node.left), right: nodes.findIndex((n) => n.node === node.right), })); const [startingNodes, terminalNodes] = ["A", "Z"].map((char) => nodes.filter((n) => n.name.endsWith(char)).map((n) => n.node), ); const result = startingNodes .map((node) => { let steps = 0; while (!terminalNodes.includes(node)) { const direction = ( { L: "left", R: "right", } as const )[directions[steps % directions.length]]; if (!direction) throw new Error("Invalid direction"); node = nodes[node][direction]; steps++; } return steps; }) .reduce((acc, x) => lcm(acc, x), 1); console.log({ result });