index.js (2765B)
1 #!/usr/bin/env node 2 3 const fs = require('node:fs'); 4 5 const grid = fs 6 .readFileSync('input', 'utf-8') 7 .split('\r\n').join('\n') 8 .split('\r').join('\n') 9 .split('\n') 10 .map(str => str.trim()) 11 .filter(str => str) 12 .map(str => str.split('')) 13 .map(row => row.map(c => c === '@')) 14 ; 15 16 const buildNeighbours = (grid) => { 17 const neighbours = grid 18 .map(row => row.map(() => 0)); 19 20 // Mark adjacent locations as having 'current' as neighbour 21 for(let y = 0; y < grid.length; y++) { 22 const row = grid[y]; 23 for(let x = 0; x < row.length ; x++) { 24 // Skip if we're empty 25 if (!grid[y][x]) continue; 26 for(let ny = -1; ny <= 1; ny++) { 27 if ((y+ny) < 0) continue; 28 if ((y+ny) >= grid.length) continue; 29 for(let nx = -1; nx <= 1; nx++) { 30 if ((x+nx) < 0) continue; 31 if ((x+nx) >= row.length) continue; 32 // Skip self 33 if (nx === 0 && ny === 0) continue; 34 neighbours[y+ny][x+nx]++; 35 } 36 } 37 } 38 } 39 40 return neighbours; 41 }; 42 43 const buildReachable = (grid, neighbours) => { 44 // Mark reachable rolls in part 1 45 let count = 0; 46 const _map = grid.map(row => row.map(() => false)); 47 for(let y = 0; y < grid.length; y++) { 48 const row = grid[y]; 49 for(let x = 0; x < row.length ; x++) { 50 // Skip if we're empty 51 if (!grid[y][x]) continue; 52 if (neighbours[y][x] >= 4) continue; 53 _map[y][x] = true; 54 count++; 55 } 56 } 57 return { 58 _map, 59 count, 60 }; 61 }; 62 63 const removeReachable = (grid, reachableMap) => { 64 for(let y = 0; y < grid.length; y++) { 65 const row = grid[y]; 66 for(let x = 0; x < row.length ; x++) { 67 if (reachableMap[y][x]) row[x] = false; 68 } 69 } 70 }; 71 72 // Debug display origin grid 73 const displayGrid = grid => { 74 process.stdout.write( 75 grid.map(row => row.map(c => c ? '@' : '.').join('')).join('\n') + '\n\n' 76 ); 77 }; 78 79 // Debug display 80 const displayReachable = (grid, reachableMap) => { 81 process.stdout.write( 82 grid.map( 83 (row,y) => row.map( 84 (roll,x) => reachableMap[y][x] ? 'x' : roll ? '@' : '.' 85 ).join('') 86 ).join('\n') + '\n\n' 87 ); 88 } 89 90 let neighbours = buildNeighbours(grid); 91 let reachable = buildReachable(grid, neighbours); 92 const part1 = reachable.count; 93 94 let totalRemoved = 0; 95 96 console.log(`Initial state:`); 97 displayGrid(grid); 98 99 while(reachable.count) { 100 console.log(`Remove ${reachable.count} rolls of paper:`); 101 totalRemoved += reachable.count; 102 displayReachable(grid, reachable._map); 103 104 removeReachable(grid, reachable._map); 105 neighbours = buildNeighbours(grid); 106 reachable = buildReachable(grid, neighbours); 107 } 108 109 process.stdout.write('\n'); 110 process.stdout.write(`------[ Part 1: ${part1} ]------\n`); 111 process.stdout.write(`------[ Part 2: ${totalRemoved} ]------\n`);