advent-of-code-2023/src/day_eight.ts

66 lines
1.8 KiB
TypeScript
Raw Normal View History

2023-12-08 08:24:48 +00:00
import {anyCharOf, newline, uniLetter, whitespace} from "parjs";
import {between, exactly, manySepBy, manyTill, stringify, then} from "parjs/combinators";
import fs from "fs";
const patternParser = anyCharOf("LR").pipe(manyTill(newline().pipe(exactly(2))));
const nodeNameParser = uniLetter().pipe(exactly(3), stringify());
const childParser = nodeNameParser.pipe(manySepBy(", "), exactly(2), between("(", ")"));
const nodeParser = nodeNameParser.pipe(then(childParser.pipe(between(" = ", whitespace()))))
const parser = patternParser.pipe(then(nodeParser.pipe(manySepBy(whitespace()))));
2023-12-08 08:24:48 +00:00
type Maybe<T> = T | undefined;
type Instruction = "L" | "R";
2023-12-08 08:24:48 +00:00
type NodeName = string;
type NodeChildren = [Maybe<NodeName>, Maybe<NodeName>];
export class DesertMap {
private readonly pattern: Instruction[];
2023-12-08 08:24:48 +00:00
private map: Record<NodeName, NodeChildren> = {};
constructor(input: string) {
const [pattern, nodes] = parser.parse(input).value;
this.pattern = pattern as Instruction[];
for (const [name, [[leftNode, rightNode]]] of nodes) {
2023-12-08 08:24:48 +00:00
if (!this.map[name]) {
this.map[name] = [undefined, undefined];
}
2023-12-08 08:24:48 +00:00
const children = [leftNode !== name ? leftNode : undefined, rightNode !== name ? rightNode : undefined];
this.map[name] = children as NodeChildren;
}
}
public stepsTo(node: string): number {
let step = 0;
2023-12-08 08:24:48 +00:00
let curr = "AAA";
2023-12-08 08:24:48 +00:00
while (curr !== node) {
const instruction = this.pattern[step % this.pattern.length];
2023-12-08 08:24:48 +00:00
const [left, right] = this.map[curr];
if (instruction === "L" && left) {
curr = left;
} else if (instruction === "R" && right) {
curr = right;
}
if (!curr) return 0;
step++;
}
return step;
}
}
export const runDayEight = () => {
const input = fs.readFileSync('./inputs/day_eight_input.txt', 'utf-8').trimEnd();
const map = new DesertMap(input);
console.log(map.stepsTo('ZZZ'));
}