import * as R from "remeda"; import Victor from "@a-robu/victor"; import { readFile } from "../05/part1.js"; export const V = (...args) => new Victor(...args); const parseLine = (line) => line.match(/[\d,]+/g).map((x) => eval(`[${x}]`)); const readInput = (...args) => R.pipe( readFile(...args), (lines) => lines.split("\n"), R.compact, // remove last line R.map(parseLine) ); export const puzzleInput = readInput(import.meta.url, "input"); export const sample = readInput(import.meta.url, "sample"); export function genCave(rocks) { const cave = {}; for (const rock of rocks) { const points = rock.map(Victor.fromArray); let from = points.shift(); while (points.length) { /** @type Victor */ const to = points.shift(); const direction = to.clone().subtract(from).normalize(); R.times(to.clone().subtract(from).length() + 1, () => { if (!cave[from.y]) cave[from.y] = {}; cave[from.y][from.x] = "#"; from.add(direction); }); from = to; } } return cave; } function pourSand(cave) { cave = R.clone(cave); let sand = 0; /** @type Victor */ let current; const maxDepth = R.pipe( cave, R.keys, R.map((x) => parseInt(x)), R.maxBy(R.identity) ); console.log({ maxDepth }); while (true) { if (!current) current = V(500, 0); if (current.y > maxDepth) return sand; const next = [ [0, 1], [-1, 1], [1, 1], ] .map((args) => V(...args)) .map((v) => v.add(current)) .find((v) => !(cave[v.y] && cave[v.y][v.x])); if (next) { current = next; } else { if (!cave[current.y]) cave[current.y] = {}; cave[current.y][current.x] = "o"; sand++; current = null; } } } export default R.createPipe(genCave, pourSand);