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 ( [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)