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 countRanges = (ranges) => { console.log({ ranges }); let newRanges = [...ranges]; let overlapCount = -1; while (overlapCount !== 0) { overlapCount = 0; newRanges = newRanges.reduce((acc, curr) => { let hasOverlap = false; const [currStart, currEnd] = curr.split("-").map((val) => val * 1); acc = (acc ?? []).map((range) => { const [start, end] = range.split("-").map((val) => val * 1); // exclude ones either before or after range if (currStart > end || currEnd < start) return range; // that means that it must overlap hasOverlap = true; return `${Math.min(currStart, start)}-${Math.max( currEnd, end )}`; }); if (hasOverlap) overlapCount++; else acc.push(curr); return acc; }, []); } console.log({ newRanges }); return newRanges.reduce((total, curr) => { const [currStart, currEnd] = curr.split("-").map((val) => val * 1); console.log(`adding ${1 + currEnd - currStart}`); return total + 1 + currEnd - currStart; // +1 because it's inclusive of the end }, 0); }; const parseData = (rows) => { let isInRanges = true; let freshRanges = []; let freshCount = 0; rows.forEach((row) => { if (isInRanges) { if (row === "") { isInRanges = false; return; } if (row.includes("-")) { freshRanges.push(row); return; } return; } }); return countRanges(freshRanges); }; const testData = ` 3-5 10-14 16-20 12-18 1 5 8 11 17 32 `.trim(); const rows = await asyncReadFile("../input.txt"); console.log(`Fresh ingredient count: ${parseData(rows)}`);