diff options
-rw-r--r-- | 10-1.hs | 41 |
1 files changed, 41 insertions, 0 deletions
@@ -0,0 +1,41 @@ +import Data.Array +import Data.List (nub) + +data Pos = Pos Int Int deriving (Eq,Ix,Ord,Show) + +type Map = Array Pos Int + +step :: Map -> Pos -> [Pos] +step m p@(Pos x y) = filter ((== 1) . subtract (m ! p) . (m !)) + . filter (`elem` indices m) + $ steps + where + steps = [ Pos (x+1) y + , Pos (x-1) y + , Pos x (y+1) + , Pos x (y-1) + ] + +width,height :: [[a]] -> Int +width = length . head +height = length + +reachable :: Map -> Pos -> [Pos] +reachable m p | m ! p == 9 = [p] + | otherwise = concatMap (reachable m) $ step m p + +score :: Map -> Pos -> Int +score m = length . nub . reachable m + +trailheads :: Map -> [Pos] +trailheads = map fst . filter ((== 0) . snd) . assocs + +parse :: [[Char]] -> Map +parse ls = listArray + (Pos 0 0, Pos (width ls - 1) (height ls - 1)) + (map (read . pure) $ concat ls) + +main :: IO () +main = do + m <- parse . lines <$> getContents + print . sum . map (score m) . trailheads $ m |