adventofcode/2022/14/part1.js

84 lines
1.8 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);