summaryrefslogtreecommitdiff
path: root/10-2.hs
diff options
context:
space:
mode:
authorLaura Orvokki Kursula <lav@vampires.gay>2024-12-10 11:59:15 +0100
committerLaura Orvokki Kursula <lav@vampires.gay>2024-12-10 12:07:08 +0100
commit78b517b79ee7cc96e336342e8845ca032faa4a17 (patch)
tree06b3e74aa993524b49536c6fa4bfc475fd5af969 /10-2.hs
parentf8d90470145abf0147d80a94e01055584f39e3cf (diff)
downloadaoc2024-78b517b79ee7cc96e336342e8845ca032faa4a17.tar.gz
aoc2024-78b517b79ee7cc96e336342e8845ca032faa4a17.zip
10-2 with memoization
Diffstat (limited to '10-2.hs')
-rw-r--r--10-2.hs27
1 files changed, 23 insertions, 4 deletions
diff --git a/10-2.hs b/10-2.hs
index cf2840c..6ee5bc2 100644
--- a/10-2.hs
+++ b/10-2.hs
@@ -1,8 +1,11 @@
+import Control.Monad.State
import Data.Array
+import Data.Foldable (toList)
data Pos = Pos Int Int deriving (Eq,Ix,Ord,Show)
type Map = Array Pos Int
+type S = State (Array Pos (Maybe Int)) Int
step :: Map -> Pos -> [Pos]
step m p@(Pos x y) = filter ((== 1) . subtract (m ! p) . (m !))
@@ -19,9 +22,19 @@ width,height :: [[a]] -> Int
width = length . head
height = length
-score :: Map -> Pos -> Int
-score m p | m ! p == 9 = 1
- | otherwise = sum . map (score m) $ step m p
+score :: Map -> Pos -> S
+score m p | m ! p == 9 = return 1
+ | otherwise = fmap sum . traverse (score' m) $ step m p
+
+score' :: Map -> Pos -> S
+score' m p = do
+ memo <- get
+ case memo ! p of
+ Just x -> return x
+ Nothing -> do
+ x <- score m p
+ modify (// [(p,Just x)])
+ return x
trailheads :: Map -> [Pos]
trailheads = map fst . filter ((== 0) . snd) . assocs
@@ -34,4 +47,10 @@ parse ls = listArray
main :: IO ()
main = do
m <- parse . lines <$> getContents
- print . sum . map (score m) . trailheads $ m
+ print
+ . sum
+ . toList
+ . flip evalState (listArray (bounds m) $ repeat Nothing)
+ . traverse (score' m)
+ . trailheads
+ $ m