module Day11 import Prelude import Node import Aoc import Data.SortedMap import Monad.State Graph : U Graph = SortedMap String (List String) part1 : Graph → Int part1 g = fst $ (count "you").runState emptyMap where count : String → State (SortedMap String Int) Int count "out" = pure 1 count node = do st <- get case lookupMap' node st of Just v => pure v Nothing => do let (Just nodes) = lookupMap' node g | _ => trace "\{show node} missing" $ pure 0 counts <- traverse count nodes let total = foldl _+_ 0 counts modify $ updateMap node total pure total data Result = MkRes Int Int Int Int emptyResult : Result emptyResult = MkRes 0 0 0 0 part2 : Graph → Int part2 g = let (MkRes none dac fft both) = fst $ (count "svr").runState emptyMap in both where addCount : String → Result → Result → Result addCount "fft" (MkRes n d f b) (MkRes n' d' f' b') = MkRes n (d) (f + f' + n') (b + b' + d') addCount "dac" (MkRes n d f b) (MkRes n' d' f' b') = MkRes n (d + d' + n') (f) (b + b' + f') addCount _ (MkRes n d f b) (MkRes n' d' f' b') = MkRes (n + n') (d + d') (f + f') (b + b') count : String → State (SortedMap String Result) Result count "out" = pure $ MkRes 1 0 0 0 count node = do st <- get case lookupMap' node st of Just v => pure v Nothing => do let (Just nodes) = lookupMap' node g | _ => trace "\{show node} missing" $ pure $ MkRes 0 0 0 0 counts <- traverse count nodes let total = foldl (addCount node) emptyResult counts modify $ updateMap node total pure total parse : String → Either String Graph parse text = do let lines = split (trim text) "\n" nodes <- traverse parseNode lines pure $ mapFromList $ nodes where parseNode : String → Either String (String × List String) parseNode txt = case split txt ": " of (a :: b :: Nil) => Right (a, split b " ") x => Left "\{show $ length x} parts" run : String -> IO Unit run fn = do putStrLn fn text <- readFile fn let (Right graph) = parse text | Left err => putStrLn err putStrLn $ "part1 " ++ show (part1 graph) putStrLn $ "part2 " ++ show (part2 graph) main : IO Unit main = do run "aoc2025/day11/eg.txt" run "aoc2025/day11/eg2.txt" run "aoc2025/day11/input.txt"