summaryrefslogtreecommitdiff
path: root/2024/10.hs
diff options
context:
space:
mode:
authorTom Smeding <tom@tomsmeding.com>2024-12-14 22:12:14 +0100
committerTom Smeding <tom@tomsmeding.com>2024-12-14 22:12:14 +0100
commit002b7037dd724d5e41d7ca0940d3e432068cfd14 (patch)
tree9e0104abaa50ae9082ec0efb206dd98e66443ce4 /2024/10.hs
parent43d2522f6b42b72264036181e0a94e3a75436c98 (diff)
10
Diffstat (limited to '2024/10.hs')
-rw-r--r--2024/10.hs24
1 files changed, 24 insertions, 0 deletions
diff --git a/2024/10.hs b/2024/10.hs
new file mode 100644
index 0000000..cbb291c
--- /dev/null
+++ b/2024/10.hs
@@ -0,0 +1,24 @@
+import qualified Data.Array as A
+import Data.Array (Array, (!))
+import Data.Foldable (toList)
+import qualified Data.Set as Set
+import Data.Bifunctor (bimap)
+
+amap :: A.Ix i => (i -> a -> b) -> Array i a -> Array i b
+amap f arr = A.listArray (A.bounds arr) (zipWith f (A.indices arr) (toList arr))
+
+main :: IO ()
+main = do
+ topo' <- map (map (read @Int . pure)) . lines <$> getContents
+ let w = length (head topo')
+ let h = length topo'
+ let topo = A.listArray ((0, 0), (w - 1, h - 1)) (concat topo')
+ let flood9 = amap (\i n -> if n == 9 then (Set.singleton i, 1::Int) else (mempty, 0)) topo
+ let inBounds (x, y) = 0 <= x && x < w && 0 <= y && y < h
+ let neighs (x, y) = filter inBounds [(x-1,y), (x+1,y), (x,y-1), (x,y+1)]
+ let stepdown mp =
+ amap (\i n -> bimap Set.unions sum $ unzip [mp ! p | p <- neighs i, topo ! p == n + 1]) topo
+ let flood = iterate stepdown flood9 !! 9
+ let (totscore, totrank) = bimap sum sum $ unzip $ map (\((s,n),_) -> (Set.size s, n)) $ filter (\(_,n) -> n == 0) $ zip (A.elems flood) (A.elems topo)
+ print totscore
+ print totrank