Advent of Code solutions
1import Control.Arrow
2import Text.Parsec
3import Data.List
4import Data.Map qualified as Map
5
6initialize ps = Map.unionsWith (+) $ fmap (flip Map.singleton 1) $ ps `zip` tail ps
7
8rule = do
9 a:b:_ <- count 2 letter
10 string " -> "
11 to <- letter
12 return $ Map.singleton (a, b) [(a, to), (to, b)]
13
14input = do
15 initial <- many letter
16 count 2 newline
17 rules <- rule `endBy` newline
18 return (initial, Map.unions rules)
19
20step rules state = Map.unionsWith (+) $ do
21 (k, v) <- Map.assocs state
22 k2 <- rules Map.! k
23 return $ Map.singleton k2 v
24
25answer contents =
26 uncurry (-)
27 $ maximum &&& minimum
28 $ Map.unionWith (+) (Map.singleton (last initial) 1)
29 $ Map.mapKeysWith (+) fst
30 $ (!! 40)
31 $ iterate (step rules)
32 $ initialize initial
33 where Right (initial, rules) = parse input "" contents
34
35main = getContents >>= print . answer