import * as R from "remeda"; import { passthru } from "../08/part1.js"; import { readFile } from "../05/part1.js"; import V from "@yanick/vyktor"; import { createLogger } from "vite"; const readInput = (...args) => R.pipe( readFile(...args), (lines) => lines.split("\n"), R.compact, // remove last line R.map((line) => line .match(/x=-?.*?y=-?\d+/g) .map((str) => str.match(/-?\d+/g).map((x) => parseInt(x))) .map((coords) => V(coords)) ) ); export const puzzleInput = readInput(import.meta.url, "input"); export const sample = readInput(import.meta.url, "sample"); /** @returns [number,number][] */ export const mergeRanges = (ranges) => { return ranges.reduce((accum, range) => { if (accum.length === 0) return [range]; if (R.last(accum)[1] < range[0]) { accum.push(range); } else { R.last(accum)[1] = Math.max(R.last(accum)[1], range[1]); } return accum; }, []); }; export const spy = passthru((x) => console.log(x)); const entriesInRange = (targetLine, entries) => { entries = R.uniqBy( entries .map(([_, beacon]) => beacon) .filter((beacon) => beacon?.y === targetLine), (x) => x.toString() ); return (range) => { return entries.filter((entry) => entry.x >= range[0] && entry.x <= range[1]) .length; }; }; export const unbeaconAtLine = (targetLine) => (entries) => R.pipe( entries, R.map(([x, y]) => [x, x.manhattanDistance(y)]), R.filter((e) => e[0].y - e[1] <= targetLine && e[0].y + e[1] >= targetLine), R.map((e) => { const l = e[1] - Math.abs(targetLine - e[0].y); return [e[0].x - l, e[0].x + l]; }), spy, (ranges) => ranges.sort((a, b) => { return a[0] - b[0] || a[1] - b[1]; }), spy, mergeRanges, spy, R.sumBy( (range) => range[1] - range[0] + 1 - entriesInRange(targetLine, entries)(range) ) ); export default unbeaconAtLine(2000000);