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, )