From 35f5601f1e270885c886a0aad32135a63f8ad5a4 Mon Sep 17 00:00:00 2001 From: Lewis Dale Date: Fri, 8 Dec 2023 08:24:48 +0000 Subject: [PATCH] Part One complete --- src/day_eight.ts | 98 ++++++++++-------------------------------------- 1 file changed, 19 insertions(+), 79 deletions(-) diff --git a/src/day_eight.ts b/src/day_eight.ts index 6743379..254029f 100644 --- a/src/day_eight.ts +++ b/src/day_eight.ts @@ -1,7 +1,6 @@ -import {anyCharOf, newline, rest, uniLetter, whitespace} from "parjs"; -import {then, many, manyTill, exactly, between, manySepBy, stringify} from "parjs/combinators"; +import {anyCharOf, newline, uniLetter, whitespace} from "parjs"; +import {between, exactly, manySepBy, manyTill, stringify, then} from "parjs/combinators"; import fs from "fs"; -import {CamelCards} from "./day_seven"; const patternParser = anyCharOf("LR").pipe(manyTill(newline().pipe(exactly(2)))); @@ -11,64 +10,16 @@ const nodeParser = nodeNameParser.pipe(then(childParser.pipe(between(" = ", whit const parser = patternParser.pipe(then(nodeParser.pipe(manySepBy(whitespace())))); -class Node { - constructor( - public label: string, - public _left?: Node, - public _right?: Node - ) { - if (this._left?.label === label) this._left = undefined; - if (this._right?.label === label) this._right = undefined; - } - - public set left(node: Node) { - if (node.label !== this.label) { - this._left = node; - } - } - - public set right(node: Node) { - if (node.label !== this.label) { - this._right = node; - } - } - - public get left(): Node | undefined { - return this._left; - } - - public get right(): Node | undefined { - return this._right; - } - - public get isBranch(): boolean { - return Boolean(this.left || this.right); - } - - /** - * Find a node by label using basic Depth-first search - */ - public find(label: string, searchedNodes: string[] = []): Node | undefined { - if (this.label === label) return this; - if (searchedNodes.includes(this.label)) return; - - if (this.left) { - const leftSearch = this.left.find(label, [...searchedNodes, this.label]); - if (leftSearch) return leftSearch; - } - - if (this.right) { - const rightSearch = this.right.find(label, [...searchedNodes, this.label]); - if (rightSearch) return rightSearch; - } - } -} +type Maybe = T | undefined; type Instruction = "L" | "R"; +type NodeName = string; +type NodeChildren = [Maybe, Maybe]; export class DesertMap { private readonly pattern: Instruction[]; - private tree?: Node; + + private map: Record = {}; constructor(input: string) { const [pattern, nodes] = parser.parse(input).value; @@ -76,38 +27,27 @@ export class DesertMap { this.pattern = pattern as Instruction[]; for (const [name, [[leftNode, rightNode]]] of nodes) { - if (!this.tree) { - this.tree = new Node(name); - } - - const parent = this.tree.find(name); - - if (!parent) { - console.log(`No parent found for label ${name}`) - } else { - - const foundLeft = this.tree.find(leftNode); - parent.left = foundLeft || new Node(leftNode); - - const foundRight = this.tree.find(rightNode); - parent.right = foundRight || new Node(rightNode); + if (!this.map[name]) { + this.map[name] = [undefined, undefined]; } + const children = [leftNode !== name ? leftNode : undefined, rightNode !== name ? rightNode : undefined]; + this.map[name] = children as NodeChildren; } } public stepsTo(node: string): number { - if (!this.tree) return 0; - let step = 0; - let curr = this.tree; + let curr = "AAA"; - while (curr.label !== node) { + while (curr !== node) { const instruction = this.pattern[step % this.pattern.length]; - if (instruction === "L" && curr.left) { - curr = curr.left; - } else if (instruction === "R" && curr.right) { - curr = curr.right; + const [left, right] = this.map[curr]; + + if (instruction === "L" && left) { + curr = left; + } else if (instruction === "R" && right) { + curr = right; } if (!curr) return 0;