Advent of Code solutions
1import Text.Parsec
2import Data.Set qualified as Set
3import Data.Map qualified as Map
4import Data.Map ((!))
5import Data.Char
6
7parseEdge = do
8 l <- many letter
9 char '-'
10 r <- many letter
11 return $ Map.fromList [(r, [l]), (l, [r])]
12
13parseGraph = Map.unionsWith (++) <$> parseEdge `endBy` newline
14
15allPaths graph = paths Set.empty "start"
16 where
17 paths visited here
18 | here == "end" = 1
19 | all isLower here && Set.member here visited = 0
20 | all isLower here = continue (Set.insert here visited) here
21 | otherwise = continue visited here
22 where
23 continue visited here = sum $ do
24 next <- graph ! here
25 return $ paths visited next
26
27answer contents = allPaths graph
28 where
29 Right graph = parse parseGraph "" contents
30
31main = getContents >>= print . answer