import { promises as fsPromises } from "node:fs"; async function asyncReadFile(filename) { try { const contents = await fsPromises.readFile(filename, "utf-8"); const arr = contents.split(/\r?\n/); return arr; } catch (err) { console.error(err); } } const countAdjacentRolls = (rows) => { const newData = structuredClone(rows); let countWithLessThanFourAdjacent = 0; rows.forEach((row, rowIndex) => { row.forEach((val, colIndex) => { if (val !== "@") return; let adjacentCount = 0; if (rowIndex > 0 && rows[rowIndex - 1][colIndex] === "@") adjacentCount++; // UM if ( rowIndex > 0 && colIndex < row.length - 1 && rows[rowIndex - 1][colIndex + 1] === "@" ) adjacentCount++; // UR if (colIndex < row.length - 1 && row[colIndex + 1] === "@") adjacentCount++; // MR if ( rowIndex < rows.length - 1 && colIndex < row.length - 1 && rows[rowIndex + 1][colIndex + 1] === "@" ) adjacentCount++; // DR if ( rowIndex < rows.length - 1 && rows[rowIndex + 1][colIndex] === "@" ) adjacentCount++; // DM if ( rowIndex < rows.length - 1 && colIndex > 0 && rows[rowIndex + 1][colIndex - 1] === "@" ) adjacentCount++; // DL if (colIndex > 0 && row[colIndex - 1] === "@") adjacentCount++; // LM if ( rowIndex > 0 && colIndex > 0 && rows[rowIndex - 1][colIndex - 1] === "@" ) adjacentCount++; // UL if (adjacentCount < 4) { countWithLessThanFourAdjacent++; newData[rowIndex][colIndex] = "x"; } else newData[rowIndex][colIndex] = "@"; }); }); return { count: countWithLessThanFourAdjacent, newRows: newData, }; }; const useTestData = false; const testDataToParse = ` ..@@.@@@@. @@@.@.@.@@ @@@@@.@.@@ @.@@@@..@. @@.@@@@.@@ .@@@@@@@.@ .@.@.@.@@@ @.@@@.@@@@ .@@@@@@@@. @.@.@@@.@. `; const dataToParse = await asyncReadFile("../input.txt"); let rollData = useTestData ? testDataToParse .trim() .split("\n") .map((val) => Array.from(val)) : dataToParse.map((val) => Array.from(val)); let lastCount = -1; let totalCount = 0; while (lastCount !== 0) { const { count, newRows } = countAdjacentRolls(rollData); console.log(`Found ${count}`); if (useTestData) console.log("\n", { newRows: newRows.map((row) => row.join("")).join(`\n`), }); totalCount += count; lastCount = count; rollData = newRows; } console.log(`Final count: ${totalCount}`);