adventofcode/2022/day08.hs

53 lines
1.5 KiB
Haskell

import Data.Set as S
import Data.List (transpose)
import Data.Char (digitToInt)
import Debug.Trace (traceShowId)
type TreeSet = S.Set (Int, Int)
toIndices :: [a] -> [Int]
toIndices = fmap fst . zip [0..]
enumerate = zip [0..]
check :: Ord t1 => [t1] -> Int -> t1 -> [Int]
check [] i max = []
check (t:ts) i req = (if t > req then (i:) else id) $ check ts (i+1) (max t req)
addRow :: (Int -> (Int, Int)) -> [Int] -> TreeSet
addRow f ts = S.fromList (Prelude.map f (left ++ right)) where
check' ts = check ts 0 (-1)
left = check' ts
right = (\x -> length ts - x - 1) <$> check' (reverse ts)
evalOutside :: [[Int]] -> TreeSet
evalOutside xs = Prelude.foldr S.union S.empty (hor ++ ver) where
hor = (\(i, ts) -> addRow (i,) ts) <$> enumerate xs
ver = (\(i, ts) -> addRow (,i) ts) <$> enumerate (transpose xs)
scenicScore :: (Int, Int) -> [[Int]] -> Int
scenicScore (x,y) ts = product $ count <$> [reverse left, right, reverse up, down] where
(left, _:right) = Prelude.splitAt x (ts !! y)
(up, _:down) = Prelude.splitAt y (transpose ts !! x)
height = ts !! y !! x
count t = length t `min` (1 + length (takeWhile (<height) t))
allScenics :: [[Int]] -> [Int]
allScenics ts = Prelude.map (\c -> scenicScore c ts) coords where
coords = [(i,j) | i <- [0..length ts-1], j <- [0..length (head ts)-1]]
main :: IO ()
main = do
x <- lines <$> readFile "inputs/day08"
let ts = fmap (fmap digitToInt) x
putStr "part 1: "
print $ S.size $ evalOutside ts
putStr "part 2: "
print $ maximum (allScenics ts)