diff --git a/day20/Part1.hs b/day20/Part1.hs index 7d9663d..39b13f5 100644 --- a/day20/Part1.hs +++ b/day20/Part1.hs @@ -4,39 +4,42 @@ import Commons import Data.Map (insert, foldr, (!), notMember) -applyModule :: Modules -> Int -> Int -> String -> Bool -> String -> (String, [String], Bool, Modules, Int, Int) -applyModule modules low high source p n - | notMember n modules = (n, [], True, modules, low, high) +applyModule :: Modules -> String -> Bool -> String -> (String, [String], Bool, Modules, Int, Int) +applyModule modules source p n + | notMember n modules = (n, [], True, modules, 0, 0) | otherwise = let m = modules ! n in case m of - Broadcaster o -> (n, o, p, modules, if not p then low + length o else low, - if p then high + length o else high) + Broadcaster o -> (n, o, p, modules, if not p then length o else 0, + if p then length o else 0) FlipFlop s o -> if not p then let newFF = FlipFlop {state = not s, outputs = o} in (n, o, not s, insert n newFF modules, - if s then low + length o else low, - if not s then high + length o else high) - else (n, [], s, modules, low, high) + if s then length o else 0, + if not s then length o else 0) + else (n, [], s, modules, 0, 0) Conjonction i o -> let newC = Conjonction {inputs = insert source p i, outputs = o} state = Data.Map.foldr (&&) True $ inputs newC - in if state then (n, o, False, insert n newC modules, low + length o, high) - else (n, o, True, insert n newC modules, low, high + length o) + in if state then (n, o, False, insert n newC modules, length o, 0) + else (n, o, True, insert n newC modules, 0, length o) -applyModules :: Modules -> Int -> Int -> String -> Bool -> [String] -> ([(String, [String], Bool)], Modules, Int, Int) -applyModules modules low high _ _ [] = ([], modules, low, high) -applyModules modules low high source p (h: t) = - let (newS, outputs, newP, newModules, newLow, newHigh) = applyModule modules low high source p h - (result, newNewModules, newNewLow, newNewHigh) = applyModules newModules newLow newHigh source p t - in ((newS, outputs, newP): result, newNewModules, newNewLow, newNewHigh) +applyModules :: Modules -> String -> Bool -> [String] -> ([(String, [String], Bool)], Modules, Int, Int) +applyModules modules _ _ [] = ([], modules, 0, 0) +applyModules modules source p (h: t) = + let (newS, outputs, newP, newModules, low, high) = applyModule modules source p h + (result, newNewModules, newLow, newHigh) = applyModules newModules source p t + in ((newS, outputs, newP): result, newNewModules, low + newLow, high + newHigh) -applySteps :: Modules -> Int -> Int -> [(String, [String], Bool)] -> (Modules, Int, Int) -applySteps modules low high [] = (modules, low, high) -applySteps modules low high ((source, names, pulse): t) = - let (result, newModules, newLow, newHigh) = applyModules modules low high source pulse names - in applySteps newModules newLow newHigh (t ++ result) +applySteps :: Modules -> [(String, [String], Bool)] -> (Modules, Int, Int) +applySteps modules [] = (modules, 0, 0) +applySteps modules ((source, names, pulse): t) = + let (result, newModules, low, high) = applyModules modules source pulse names + (newNewModules, newLow, newHigh) = applySteps newModules (t ++ result) + in (newNewModules, low + newLow, high + newHigh) pressButton :: Modules -> (Modules, Int, Int) -pressButton modules = applySteps modules 1 0 [("button", ["broadcaster"], False)] +pressButton modules = + let (newModules, low, high) = applySteps modules [("button", ["broadcaster"], False)] + in (newModules, low + 1, high) pressButtonNTimes' :: Modules -> Int -> Int -> Int -> Int -> (Int, Int) pressButtonNTimes' modules low high i n