summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--10-1.hs41
1 files changed, 41 insertions, 0 deletions
diff --git a/10-1.hs b/10-1.hs
new file mode 100644
index 0000000..afeff45
--- /dev/null
+++ b/10-1.hs
@@ -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