import fs from 'node:fs'; const file = fs.readFileSync('./2025/inputs/4').toString(); const lines = file.split("\n").map(e => e.split("")) const yLength = lines.length const xLength = lines[0].length const table: Node[][] = [] const nodes: Node[] = [] class Node { neighbours = 0 constructor(public x: number, public y: number, public isPaper: boolean) { nodes.push(this) } /** * Because we iterate from N-W to S-E * We only need to lookup the S-E neighbours * x x x * x o c * c c c */ public calculateNeighbours() { // x x x // x o c // x x x if (this.x + 1 < xLength) { const w = table[this.y][this.x + 1] if (w.isPaper) { this.neighbours++ } if (this.isPaper) { w.neighbours++ } } if (this.y + 1 < yLength) { // x x x // x o x // x c x const s = table[this.y + 1][this.x] if (s.isPaper) { this.neighbours++ } if (this.isPaper) { s.neighbours++ } // x x x // x o x // x x c if (this.x + 1 < xLength) { const se = table[this.y + 1][this.x + 1] if (se.isPaper) { this.neighbours++ } if (this.isPaper) { se.neighbours++ } } // x x x // x o x // c x x if (this.x - 1 >= 0) { const sw = table[this.y + 1][this.x - 1] if (sw.isPaper) { this.neighbours++ } if (this.isPaper) { sw.neighbours++ } } } } } table.push(...lines.map((l, i) => l.map((e, j) => new Node(j, i, e == "@")))) nodes.forEach(n => n.calculateNeighbours()) let removed = 0 while (true) { const accessible = nodes.filter(n => n.neighbours < 4 && n.isPaper) if (accessible.length == 0) { break } removed += accessible.length accessible.forEach(n => { n.isPaper = false }) nodes.forEach(n => { n.neighbours = 0 }) nodes.forEach(n => n.calculateNeighbours()) } console.log(removed)