3 import Prelude hiding (round)
5 import Control.Monad.ST
6 import Control.Monad.Loops
8 import qualified Data.Vector.Unboxed.Mutable as V
13 do let seed = [20, 0, 1, 11, 6, 3]
19 part1 seed = runGame seed 2020
20 part2 seed = runGame seed 30000000
22 runGame seed roundsNeeded =
24 do (round, word, history) <- seedGame seed roundsNeeded
25 gameLoop roundsNeeded round word history
28 -- gameLoop targetRound round word history =
29 -- do ( gameStep round word history
30 -- `untilM_` (do r <- readSTRef round
31 -- return $ r == targetRound)
35 -- gameLoop targetRound round word history =
36 -- do untilM_ (gameStep round word history )
37 -- (do r <- readSTRef round
38 -- return $ r == targetRound )
41 -- gameLoop targetRound round word history =
42 -- do whileM_ (do r <- readSTRef round
43 -- return $ r /= targetRound )
44 -- (gameStep round word history )
47 gameLoop targetRound round word history =
48 do whileM_ (do r <- readSTRef round
49 return $ r /= targetRound )
50 $ gameStep round word history
53 seedGame seed historySize =
54 do round <- newSTRef $ length seed
55 word <- newSTRef $ last seed
56 history <- V.replicate historySize 0
57 forM_ (zip (init seed) [1..]) $ \(t, s) -> V.write history t s
58 return (round, word, history)
60 gameStep :: STRef s Int -> STRef s Int -> V.MVector s Int -> ST s ()
61 gameStep round word history =
62 do roundVal <- readSTRef round
63 wordVal <- readSTRef word
64 wordH <- V.read history wordVal
65 let word' = speakWord wordH roundVal
66 V.write history wordVal roundVal
67 modifySTRef round (+1)
71 speakWord :: Int -> Int -> Int
73 speakWord prev now = now - prev