import fs from 'node:fs' function init(filename) { const data = fs.readFileSync(filename, { encoding: 'utf-8' }, data => data) const desertmap = new DesertMap( data.split('\n\n')[0].split(''), data.split('\n\n')[1] ) desertmap.navigate_ghosts() } class DesertMap { instructions = [] map = "" #route = [] constructor(instructions, map) { this.instructions = instructions this.map = map this.#route = [] this.steps = 0 } setup() { const matches = [...this.map.matchAll(/(\w+) = \((\w+), (\w+)\)/gm)] matches.forEach(match => { this.#route.push({ from: match[1], L: match[2], R: match[3] }) }) } run(towards, from) { if (!this.steps && !from) { return this.#route.find(route => route.from === 'AAA')[towards] } return this.#route.find(route => route.from === from)[towards] } navigate_brute() { this.setup() let i = 0 let start = this.#route.filter(route => route.from[2] === 'A') .map(route => route.from) while (i < this.instructions.length | true) { start = start.map(route => this.run(this.instructions[i], route)) ++this.steps if (start.filter(route => route[2] === 'Z').length === start.length) { console.log(this.steps) return true } i = this.instructions.length - i === 1 ? 0 : i + 1 } console.log(this.steps + 1) } lcm(numbers) { function gcd(a, b) { if (b === 0) { return a; } return gcd(b, a % b); } return numbers.reduce((a, b) => a * b / gcd(a, b)); } navigate_ghosts() { this.setup() let routes = this.#route.filter(route => route.from[2] === 'A') .map(route => route.from) let results = routes.map(route => { let i = 0 let steps = 0 while (i < this.instructions.length | true) { route = this.run(this.instructions[i], route) ++steps if (route[2] === 'Z') { return steps } i = this.instructions.length - i === 1 ? 0 : i + 1 } }) console.log(`LCM of ${results.join(", ")}`) console.log(this.lcm(results)) } navigate() { this.setup() let i = 0 while (i < this.instructions.length | true) { let from = this.run(this.instructions[i], from) ++this.steps console.log(i, from, this.steps) if (from === 'ZZZ') { return false } i = this.instructions.length - i === 1 ? 0 : i + 1 } console.log(this.steps) } } init('input.txt')