diff options
author | Laura Orvokki Kursula <lav@vampires.gay> | 2024-12-10 11:59:15 +0100 |
---|---|---|
committer | Laura Orvokki Kursula <lav@vampires.gay> | 2024-12-10 12:07:08 +0100 |
commit | 78b517b79ee7cc96e336342e8845ca032faa4a17 (patch) | |
tree | 06b3e74aa993524b49536c6fa4bfc475fd5af969 /10-2.hs | |
parent | f8d90470145abf0147d80a94e01055584f39e3cf (diff) | |
download | aoc2024-78b517b79ee7cc96e336342e8845ca032faa4a17.tar.gz aoc2024-78b517b79ee7cc96e336342e8845ca032faa4a17.zip |
10-2 with memoization
Diffstat (limited to '10-2.hs')
-rw-r--r-- | 10-2.hs | 27 |
1 files changed, 23 insertions, 4 deletions
@@ -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 |