Files
newt/aoc2025/Day11.newt
2025-12-10 22:05:52 -08:00

79 lines
2.3 KiB
Agda
Raw Blame History

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"