Advent of Code 2025
1module Day11 where
2
3import Debug.Trace
4import qualified Data.Map as Map
5import Data.Map (Map)
6
7parse :: String -> Map String [String]
8parse = Map.fromList . map parseLine . lines
9 where parseLine :: String -> (String, [String])
10 parseLine s =
11 let w = words s
12 in (init $ head w, tail w)
13
14pathCount :: Map String [String] -> String -> String -> Int
15pathCount edges from to =
16 let m = Map.fromList [(v, ct v) | v <- Map.keys edges]
17 ct v = if v == to then 1 else sum $ map (m Map.!) (edges Map.! v)
18 in ct from
19
20part1 :: String -> String
21part1 input =
22 let edges = Map.insert "out" [] $ parse input
23 in show $ pathCount edges "you" "out"
24
25
26pathCount2 :: Map String [String] -> String -> String -> Int
27pathCount2 edges from to =
28 let neitherMemo = Map.fromList [(v, neither v) | v <- Map.keys edges]
29 neither v = if v == to then 1 else sum $ map (neitherMemo Map.!) (edges Map.! v)
30
31 withDacMemo = Map.fromList [(v, withDac v) | v <- Map.keys edges]
32 withDac v = if v == to then
33 0
34 else if v == "dac" then
35 sum $ map (neitherMemo Map.!) (edges Map.! v)
36 else
37 sum $ map (withDacMemo Map.!) (edges Map.! v)
38
39 withFftMemo = Map.fromList [(v, withFft v) | v <- Map.keys edges]
40 withFft v = if v == to then
41 0
42 else if v == "fft" then
43 sum $ map (neitherMemo Map.!) (edges Map.! v)
44 else
45 sum $ map (withFftMemo Map.!) (edges Map.! v)
46
47 withBothMemo = Map.fromList [(v, withBoth v) | v <- Map.keys edges]
48 withBoth v = if v == to then
49 0
50 else if v == "dac" then
51 sum $ map (withFftMemo Map.!) (edges Map.! v)
52 else if v == "fft" then
53 sum $ map (withDacMemo Map.!) (edges Map.! v)
54 else
55 sum $ map (withBothMemo Map.!) (edges Map.! v)
56 in withBoth from
57
58part2 :: String -> String
59part2 input =
60 let edges = Map.insert "out" [] $ parse input
61 in show $ pathCount2 edges "svr" "out"