/ 2020 / 15 / p1.hs
p1.hs
 1  import Control.Monad.State
 2  import Data.Map (Map)
 3  import Data.Map qualified as Map
 4  import Text.Parsec
 5  
 6  int :: Parsec String u Int
 7  int = read <$> many digit
 8  
 9  parseInput = int `sepBy` char ','
10  
11  run :: Int -> [Int] -> Int
12  run n st = evalState (run_ n) (Map.fromList $ zip (init st) [1 ..])
13    where
14      run_ :: Int -> Control.Monad.State.State (Map Int Int) Int
15      run_ n | n <= length st = return $ st !! (n - 1)
16      run_ i = do
17        prev <- run_ $ i - 1
18        before <- gets (Map.lookup prev)
19        let next = maybe 0 (i - 1 -) before
20         in do
21              modify (Map.insert prev (i - 1))
22              return next
23  
24  answer contents = run 2020 input
25    where
26      Right input = parse parseInput "" contents
27  
28  main :: IO ()
29  main = getContents >>= print . answer