AoC-2022-Nix/days/8/solution.nix
zuckerberg 43e24c6db9 Day 8
2022-12-11 11:03:36 -07:00

55 lines
2.0 KiB
Nix

with import ../../util.nix;
let
input = map (line: map toInt (stringToCharacters line)) (splitString "\n" (readFile ./input));
input' = transpose input;
visibleTrees =
let
# counts the number of trees visible from a starting
hiddenTreesLineDir = l:
(foldl
(acc: x:
if x > acc.highest then { highest = x; out = acc.out ++ [true]; } # visible
else { inherit (acc) highest; out = acc.out ++ [false]; }) # hidden
{ highest = -1; out = []; } l).out;
hiddenTreesLine = l:
mergeLists or (hiddenTreesLineDir l) (reverseList (hiddenTreesLineDir (reverseList l)));
hiddenTreesGrid = map hiddenTreesLine;
hiddenTreesRows = hiddenTreesGrid input;
hiddenTreesCols = hiddenTreesGrid input';
mergeGrid = f:
let
w = length hiddenTreesCols;
h = length hiddenTreesRows;
in genList (i: genList (j: f (elemAt (elemAt hiddenTreesCols i) j) (elemAt (elemAt hiddenTreesRows j) i) ) h) w;
in mergeGrid or;
countVisibleRow = l: sum (map boolToInt l);
countVisible = sum (map countVisibleRow visibleTrees);
# number of trees visible from each point as a score
visibleScore =
let
getCol = x: map (l: elemAt l x) input;
getRow = y: elemAt input y;
left = x: l: reverseList (take x l);
right = x: l: drop (x+1) l;
visibleCountDir = treeHeight: l:
(foldl (acc: x:
if acc.stop == false then
if x >= treeHeight then { cnt = acc.cnt +1; stop = true; }
else { cnt = acc.cnt +1; stop = false; }
else acc) { cnt = 0; stop = false; } l).cnt;
treeScore = x: y: v:
(visibleCountDir v (left x (getRow y)))
* (visibleCountDir v (right x (getRow y)))
* (visibleCountDir v (left y (getCol x)))
* (visibleCountDir v (right y (getCol x)));
in map2D treeScore input;
maxVisibleScore = foldr (x: max (maxList x)) 0 visibleScore;
in rec {
part1 = countVisible;
part2 = maxVisibleScore;
}