2022-12-08 16:15:24 +00:00
|
|
|
import * as R from "remeda";
|
|
|
|
import { readFile } from "../05/part1.js";
|
2022-12-08 16:18:50 +00:00
|
|
|
import Victor from "@a-robu/victor";
|
2022-12-08 16:15:24 +00:00
|
|
|
|
|
|
|
const V = (...args) => new Victor(...args);
|
|
|
|
|
|
|
|
const readInput = (...args) =>
|
|
|
|
readFile(...args)
|
|
|
|
.split("\n")
|
|
|
|
.filter((x) => x)
|
2022-12-08 16:18:50 +00:00
|
|
|
.map((l) => l.split("").map((x) => parseInt(x)));
|
2022-12-08 16:15:24 +00:00
|
|
|
|
2022-12-08 21:19:44 +00:00
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
2022-12-08 16:15:24 +00:00
|
|
|
export function generateVisibilityGrid(forest) {
|
2022-12-08 16:18:50 +00:00
|
|
|
const size = forest.length;
|
|
|
|
const visibility = Array(size)
|
|
|
|
.fill(null)
|
|
|
|
.map(() => Array(size).fill(false));
|
2022-12-08 16:15:24 +00:00
|
|
|
|
2022-12-08 16:18:50 +00:00
|
|
|
// top
|
|
|
|
const positions = R.range(size)(0).map((x) => ({
|
|
|
|
height: -1,
|
|
|
|
position: V(x, -1),
|
|
|
|
inc: V(0, 1),
|
|
|
|
}));
|
2022-12-08 16:15:24 +00:00
|
|
|
|
2022-12-08 16:18:50 +00:00
|
|
|
// bottom
|
|
|
|
positions.push(
|
|
|
|
...R.range(size)(0).map((x) => ({
|
|
|
|
height: -1,
|
|
|
|
position: V(x, size),
|
|
|
|
inc: V(0, -1),
|
|
|
|
}))
|
|
|
|
);
|
2022-12-08 16:15:24 +00:00
|
|
|
|
2022-12-08 16:18:50 +00:00
|
|
|
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),
|
|
|
|
}))
|
|
|
|
);
|
2022-12-08 16:15:24 +00:00
|
|
|
|
2022-12-08 16:18:50 +00:00
|
|
|
while (positions.length) {
|
|
|
|
const pos = positions.shift();
|
|
|
|
pos.position.add(pos.inc);
|
2022-12-08 16:15:24 +00:00
|
|
|
|
2022-12-08 21:19:44 +00:00
|
|
|
if (outOfBound(size)(pos.position)) continue;
|
2022-12-08 16:15:24 +00:00
|
|
|
|
2022-12-08 16:18:50 +00:00
|
|
|
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];
|
2022-12-08 16:15:24 +00:00
|
|
|
}
|
|
|
|
|
2022-12-08 16:18:50 +00:00
|
|
|
positions.push(pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
return visibility;
|
2022-12-08 16:15:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export const puzzleInput = readInput(import.meta.url, "input");
|
|
|
|
export const sample = readInput(import.meta.url, "sample");
|
|
|
|
|
2022-12-08 21:27:32 +00:00
|
|
|
export const passthru = (func) => (arg) => {
|
|
|
|
func(arg);
|
|
|
|
return arg;
|
|
|
|
};
|
|
|
|
|
|
|
|
export const printMap = passthru((forest) =>
|
|
|
|
forest.forEach((line) => console.log(line.join(" ")))
|
|
|
|
);
|
2022-12-08 16:15:24 +00:00
|
|
|
|
|
|
|
export default R.createPipe(
|
2022-12-08 16:18:50 +00:00
|
|
|
generateVisibilityGrid,
|
|
|
|
R.flatten,
|
|
|
|
R.countBy(R.identity)
|
2022-12-08 16:15:24 +00:00
|
|
|
);
|