From c938a2e3cd3f4236c977c122f845e2d9d2b81101 Mon Sep 17 00:00:00 2001 From: Steve Dunham Date: Wed, 10 Dec 2025 22:05:52 -0800 Subject: [PATCH] Day 11 --- aoc2025/Day11.newt | 78 +++++++++++++++++++++++++++++++++++++++++++ aoc2025/day11/eg.txt | 10 ++++++ aoc2025/day11/eg2.txt | 13 ++++++++ 3 files changed, 101 insertions(+) create mode 100644 aoc2025/Day11.newt create mode 100644 aoc2025/day11/eg.txt create mode 100644 aoc2025/day11/eg2.txt diff --git a/aoc2025/Day11.newt b/aoc2025/Day11.newt new file mode 100644 index 0000000..ba188d5 --- /dev/null +++ b/aoc2025/Day11.newt @@ -0,0 +1,78 @@ +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" diff --git a/aoc2025/day11/eg.txt b/aoc2025/day11/eg.txt new file mode 100644 index 0000000..01e5b43 --- /dev/null +++ b/aoc2025/day11/eg.txt @@ -0,0 +1,10 @@ +aaa: you hhh +you: bbb ccc +bbb: ddd eee +ccc: ddd eee fff +ddd: ggg +eee: out +fff: out +ggg: out +hhh: ccc fff iii +iii: out diff --git a/aoc2025/day11/eg2.txt b/aoc2025/day11/eg2.txt new file mode 100644 index 0000000..2bd407b --- /dev/null +++ b/aoc2025/day11/eg2.txt @@ -0,0 +1,13 @@ +svr: aaa bbb +aaa: fft +fft: ccc +bbb: tty +tty: ccc +ccc: ddd eee +ddd: hub +hub: fff +eee: dac +dac: fff +fff: ggg hhh +ggg: out +hhh: out \ No newline at end of file