adventofcode/2022/14/part1.js

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