Redone day 7 with the Graphite graph library
[advent-of-code-20.git] / advent15 / src / advent15.hs
1 -- import Debug.Trace
2
3 import Prelude hiding (round)
4 import Control.Monad
5 import Control.Monad.ST
6 import Data.STRef
7 import qualified Data.Vector.Unboxed.Mutable as V
8
9
10 type STInt s = STRef s Int
11 type VInt s = V.MVector s Int
12
13 main :: IO ()
14 main =
15 do let seed = [20, 0, 1, 11, 6, 3]
16 -- print seed
17 print $ part1 seed
18 print $ part2 seed
19
20
21 part1 seed = runGame seed 2020
22 part2 seed = runGame seed 30000000
23
24 runGame :: [Int] -> Int -> Int
25 runGame seed roundsNeeded =
26 runST $
27 do (round, word, history) <- seedGame seed roundsNeeded
28 gameSteps roundsNeeded round word history
29 readSTRef word
30
31 seedGame :: [Int] -> Int -> ST s (STInt s, STInt s, VInt s)
32 seedGame seed historySize =
33 do round <- newSTRef $ length seed
34 word <- newSTRef $ last seed
35 history <- V.replicate historySize 0
36 forM_ (zip (init seed) [1..]) $ \(t, s) -> V.write history t s
37 return (round, word, history)
38
39
40 -- gameSteps :: Int -> STRef s Int -> STRef s Int -> V.MVector s Int -> ST s ()
41 gameSteps :: Int -> STInt s -> STInt s -> VInt s -> ST s ()
42 gameSteps targetRound round word history =
43 do roundVal <- readSTRef round
44 if roundVal == targetRound
45 then return ()
46 else do
47 wordVal <- readSTRef word
48 wordH <- V.read history wordVal
49 let word' = speakWord wordH roundVal
50 V.write history wordVal roundVal
51 modifySTRef round (+1)
52 writeSTRef word word'
53 gameSteps targetRound round word history
54
55
56 speakWord :: Int -> Int -> Int
57 speakWord 0 _ = 0
58 speakWord prev now = now - prev
59
60