From 2d398f7832f2f1675ae6f77ebc7351384d436f78 Mon Sep 17 00:00:00 2001 From: Eric Mertens Date: Mon, 18 Dec 2023 23:21:17 -0800 Subject: [PATCH] always have else --- solutions/src/2023/19.hs | 48 ++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/solutions/src/2023/19.hs b/solutions/src/2023/19.hs index 5843741..1415e01 100644 --- a/solutions/src/2023/19.hs +++ b/solutions/src/2023/19.hs @@ -50,54 +50,50 @@ stageTH -- 127517902575337 main :: IO () main = - do (workflows, parts) <- [format|2023 19 (%a+{(@V>%d:%a+|@V<%d:%a+|%a+)&,}%n)*%n({x=%d,m=%d,a=%d,s=%d}%n)*|] - let workflowMap = Map.fromList [(k, map toRule v) | (k, v) <- workflows] + do (workflows, parts) <- [format|2023 19 (%a+{((@V>%d:%a+|@V<%d:%a+),)*%a+}%n)*%n({x=%d,m=%d,a=%d,s=%d}%n)*|] + let workflowMap = Map.fromList [(k, (map toRule rs, e)) | (k, rs, e) <- workflows] print (sum [rating1 workflowMap "in" p | p <- parts]) let full = Dim 1 4001 Pt print (rating2 workflowMap "in" (full,full,full,full)) -data Rule = LessThan V Int String | GreaterThan V Int String | Else String +data Rule = LessThan V Int String | GreaterThan V Int String -toRule :: Either (Either (V, Int, String) (V, Int, String)) String -> Rule -toRule (Left (Left (v, n, lbl))) = GreaterThan v n lbl -toRule (Left (Right (v, n, lbl))) = LessThan v n lbl -toRule (Right lbl ) = Else lbl +toRule :: Either (V, Int, String) (V, Int, String) -> Rule +toRule (Left (v, n, lbl)) = GreaterThan v n lbl +toRule (Right (v, n, lbl)) = LessThan v n lbl -rating1 :: Map String [Rule] -> String -> (Int, Int, Int, Int) -> Int +rating1 :: Map String ([Rule], String) -> String -> (Int, Int, Int, Int) -> Int rating1 _ "A" (x, m, a, s) = x + m + a + s rating1 _ "R" _ = 0 -rating1 workflows k p = process (workflows Map.! k) +rating1 workflows k p = + case workflows Map.! k of + (rs, el) -> foldr process (rating1 workflows el p) rs where - process (GreaterThan var n tgt : rest) + process (GreaterThan var n tgt) rest | lkp p var > n = rating1 workflows tgt p - | otherwise = process rest - process (LessThan var n tgt : rest) + | otherwise = rest + process (LessThan var n tgt) rest | lkp p var < n = rating1 workflows tgt p - | otherwise = process rest - process (Else tgt : _) = rating1 workflows tgt p - process [] = error "bad rule" + | otherwise = rest -rating2 :: Map String [Rule] -> String -> (Box' 1, Box' 1, Box' 1, Box' 1) -> Int +rating2 :: Map String ([Rule], String) -> String -> (Box' 1, Box' 1, Box' 1, Box' 1) -> Int rating2 _ "A" (x,m,a,s) = size x * size m * size a * size s rating2 _ "R" _ = 0 -rating2 workflows k p0 = - process (workflows Map.! k) p0 +rating2 workflows k p0 = process (workflows Map.! k) p0 where - process (GreaterThan var n tgt : rest) p = + process (GreaterThan var n tgt : rest, el) p = case lkp p var of Dim lo hi Pt -> - (if n+1 < hi then rating2 workflows tgt (set p var (Dim (n+1) hi Pt)) else 0) + - (if lo < n+1 then process rest (set p var (Dim lo (n+1) Pt)) else 0) + (if lo < n+1 then process (rest, el) (set p var (Dim lo (n+1) Pt)) else 0) + + (if n+1 < hi then rating2 workflows tgt (set p var (Dim (n+1) hi Pt)) else 0) - process (LessThan var n tgt : rest) p = + process (LessThan var n tgt : rest, el) p = case lkp p var of Dim lo hi Pt -> (if lo < n then rating2 workflows tgt (set p var (Dim lo n Pt) ) else 0) + - (if n < hi then process rest (set p var (Dim n hi Pt)) else 0) + (if n < hi then process (rest, el) (set p var (Dim n hi Pt)) else 0) - process (Else tgt : _) p = rating2 workflows tgt p - - process [] _ = error "bad rule" + process ([], el) p = rating2 workflows el p lkp :: (a, a, a, a) -> V -> a lkp (x,_,_,_) Vx = x