3 import Prelude hiding (round)
4 import qualified Data.IntMap.Strict as M
7 data Game = Game { round :: Int
9 , history :: M.IntMap Int
14 do let seed = [20, 0, 1, 11, 6, 3]
19 part1 = word . (gameRound 2020) . seedGame
20 -- part2 = word . (gameRound 30000000) . seedGame
21 part2 g0 = (word gf, maximum $ M.keys $ history gf)
22 where gf = (gameRound 30000000) $ seedGame g0
25 seedGame seed = Game {..}
26 where round = length seed
28 history = M.fromList $ zip (init seed) [1..]
30 infiniteGame g = iterate gameStep g
32 gameRound r game0 = head $ dropWhile notYet $ infiniteGame game0
33 where notYet game = round game < r
36 Game { round = round + 1
41 word' = speakWord (M.lookup word history) round
42 history' = M.insert word round history
44 speakWord Nothing _ = 0
45 speakWord (Just prev) now = now - prev