86 lines
2.0 KiB
JavaScript
86 lines
2.0 KiB
JavaScript
|
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,
|
||
|
)
|