3 import Prelude hiding (round)
4 import qualified Data.IntMap.Strict as M
6 data Game = Game { round :: Int
8 , history :: M.IntMap Int
13 do let seed = [20, 0, 1, 11, 6, 3]
18 part1 = word . (gameRound 2020) . seedGame
19 -- part2 = word . (gameRound 30000000) . seedGame
20 part2 g0 = (word gf, maximum $ M.keys $ history gf)
21 where gf = (gameRound 30000000) $ seedGame g0
24 seedGame seed = Game {..}
25 where round = length seed
27 history = M.fromList $ zip (init seed) [1..]
29 infiniteGame g = iterate gameStep g
31 gameRound r game0 = head $ dropWhile notYet $ infiniteGame game0
32 where notYet game = round game < r
35 Game { round = round + 1
40 word' = speakWord (M.lookup word history) round
41 history' = M.insert word round history
43 speakWord Nothing _ = 0
44 speakWord (Just prev) now = now - prev