105 lines
3 KiB
TypeScript
105 lines
3 KiB
TypeScript
import * as ink from 'https://deno.land/x/ink/mod.ts';
|
|
const input = Deno.readTextFileSync('./input.txt').trimEnd();
|
|
|
|
type TreeMap = {
|
|
width: number;
|
|
height: number;
|
|
data: Array<number[]>;
|
|
};
|
|
|
|
function genData(map: string): TreeMap {
|
|
const treeMap: Partial<TreeMap> = {};
|
|
treeMap.data = map.split('\n')
|
|
.map((line) =>
|
|
[...line].map(
|
|
(char) => parseInt(char),
|
|
)
|
|
) as Array<number[]>;
|
|
treeMap.height = treeMap.data.length;
|
|
treeMap.width = treeMap.data[0].length;
|
|
return treeMap as TreeMap;
|
|
}
|
|
|
|
const treeMap = genData(input);
|
|
const visibleTrees: Set<number> = new Set();
|
|
|
|
function checkTrees(treeMap: TreeMap, reverse = false) {
|
|
// Create initial max values (shallow copy)
|
|
const pos = reverse ? -1 : 0;
|
|
const colMax = treeMap.data.at(pos)!.map((n) => n);
|
|
const rowMax = treeMap.data.map((row) => row.at(pos) as number);
|
|
|
|
for (
|
|
let row = reverse ? treeMap.height - 2 : 1;
|
|
reverse ? row > 0 : row < treeMap.height - 1;
|
|
reverse ? row-- : row++
|
|
) {
|
|
for (
|
|
let col = reverse ? treeMap.width - 2 : 1;
|
|
reverse ? col > 0 : col < treeMap.width - 1;
|
|
reverse ? col-- : col++
|
|
) {
|
|
const curVal = treeMap.data[row][col];
|
|
if (curVal > rowMax[row]) {
|
|
rowMax[row] = curVal;
|
|
visibleTrees.add(treeMap.width * row + col);
|
|
}
|
|
if (curVal > colMax[col]) {
|
|
colMax[col] = curVal;
|
|
visibleTrees.add(treeMap.width * row + col);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function findMaxView(treeMap: TreeMap): number {
|
|
let max = 0;
|
|
for (let row = 1; row < treeMap.height - 2; row++) {
|
|
for (let col = 1; col < treeMap.width - 2; col++) {
|
|
const left = treeMap.data[row].slice(0, col);
|
|
left.reverse();
|
|
const right = treeMap.data[row].slice(col + 1);
|
|
const up = treeMap.data.slice(0, row).map((row) => row.at(col)!);
|
|
up.reverse();
|
|
const down = treeMap.data.slice(row + 1).map((row) => row.at(col)!);
|
|
const score = [0, 0, 0, 0];
|
|
const curVal = treeMap.data[row][col];
|
|
for (const [index, direction] of [up, right, left, down].entries()) {
|
|
while (score[index] < direction.length - 1 && curVal > direction[score[index]]) {
|
|
score[index] += 1;
|
|
}
|
|
score[index] += 1;
|
|
}
|
|
const sum = score.reduce((prev, cur) => prev * cur, 1);
|
|
|
|
if (sum > max) {
|
|
max = sum;
|
|
}
|
|
}
|
|
}
|
|
return max;
|
|
}
|
|
|
|
function printTreeMap(treeMap: TreeMap, visibleTrees: Set<number>) {
|
|
for (const [row, line] of treeMap.data.entries()) {
|
|
console.log(ink.colorize(
|
|
line.map((tree, col) => {
|
|
if (visibleTrees.has(row * treeMap.width + col)) {
|
|
return `<bg-black><red>${tree}</red></bg-black>`;
|
|
}
|
|
return tree.toString();
|
|
}).join(''),
|
|
));
|
|
}
|
|
}
|
|
|
|
const p1 = findMaxView(treeMap);
|
|
|
|
checkTrees(treeMap);
|
|
checkTrees(treeMap, true);
|
|
const p2 = treeMap.width * 2 + treeMap.height * 2 - 4 + visibleTrees.size;
|
|
|
|
printTreeMap(treeMap, visibleTrees);
|
|
console.log('Solution Part 1:', p1);
|
|
console.log('Solution Part 2:', p2);
|