AOC2022/src/08_TreetopTreeHouse/TreetopTreeHouse.ts
2022-12-10 01:30:40 +01:00

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