Skip to content

Commit

Permalink
always have else
Browse files Browse the repository at this point in the history
  • Loading branch information
glguy committed Dec 19, 2023
1 parent f270f53 commit 2d398f7
Showing 1 changed file with 22 additions and 26 deletions.
48 changes: 22 additions & 26 deletions solutions/src/2023/19.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 2d398f7

Please sign in to comment.