import * as R from "remeda"; import { readFile } from "../05/part1.js"; import Victor from "@a-robu/victor"; const V = (...args) => new Victor(...args); const readInput = (...args) => readFile(...args) .split("\n") .filter((x) => x) .map((l) => l.split("").map((x) => parseInt(x))); export const outOfBound = (size) => (pos) => { if (Math.min(pos.x, pos.y) < 0) return true; if (Math.max(pos.x, pos.y) >= size) return true; return false; }; export function generateVisibilityGrid(forest) { const size = forest.length; const visibility = Array(size) .fill(null) .map(() => Array(size).fill(false)); // top const positions = R.range(size)(0).map((x) => ({ height: -1, position: V(x, -1), inc: V(0, 1), })); // bottom positions.push( ...R.range(size)(0).map((x) => ({ height: -1, position: V(x, size), inc: V(0, -1), })) ); positions.push( ...R.range(size)(0).map((x) => ({ height: -1, position: V(-1, x), inc: V(1, 0), })) ); positions.push( ...R.range(size)(0).map((x) => ({ height: -1, position: V(size, x), inc: V(-1, 0), })) ); while (positions.length) { const pos = positions.shift(); pos.position.add(pos.inc); if (outOfBound(size)(pos.position)) continue; if (forest[pos.position.x][pos.position.y] > pos.height) { visibility[pos.position.x][pos.position.y] = true; pos.height = forest[pos.position.x][pos.position.y]; } positions.push(pos); } return visibility; } export const puzzleInput = readInput(import.meta.url, "input"); export const sample = readInput(import.meta.url, "sample"); export const passthru = (func) => (arg) => { func(arg); return arg; }; export const printMap = passthru((forest) => forest.forEach((line) => console.log(line.join(" "))) ); export default R.createPipe( generateVisibilityGrid, R.flatten, R.countBy(R.identity) );