3 | import Data.List.Lazy
7 | digit : Char -> Integer
8 | digit c = cast c - cast '0'
10 | Mul : TyRE (Integer, Integer)
12 | f `map` r "mul\\(`[0-9]+`,`[0-9]+`\\)"
14 | f : (String, String) -> (Integer, Integer)
16 | let raw : Maybe (Integer, Integer) =
17 | do x <- parseInteger x
23 | (idris_crash "Somehow failed to convert regex validated numbers: \{show (x,y)}")
26 | data Cmd : Type where
29 | CMul : Integer -> Integer -> Cmd
33 | show CDont = "don't()"
34 | show (CMul i j) = "mul(\{show i},\{show j})"
36 | pairToCMul : (Integer, Integer) -> Cmd
37 | pairToCMul (x, y) = CMul x y
40 | DoR = f `map` r "do\\(\\)"
45 | DontR = f `map` r "don't\\(\\)"
50 | MulR = pairToCMul `map` Mul
53 | CmdR = DoR `or` (DontR `or` MulR)
55 | justMatches : DisjointMatches a -> LazyList a
56 | justMatches (Suffix cs) = []
57 | justMatches (Cons cs x y) =
58 | let rest = justMatches y
61 | handleProgram : LazyList Cmd -> Integer
62 | handleProgram x = handleProgram' x True 0
64 | handleProgram' : LazyList Cmd -> (enabled : Bool) -> (acc : Integer) -> Integer
65 | handleProgram' [] enabled acc = acc
66 | handleProgram' (CDo :: xs) enabled acc =
67 | handleProgram' xs True acc
68 | handleProgram' (CDont :: xs) enabled acc =
69 | handleProgram' xs False acc
70 | handleProgram' ((CMul _ _) :: xs) False acc =
71 | handleProgram' xs False acc
72 | handleProgram' ((CMul x y) :: xs) True acc =
73 | handleProgram' xs True (acc + (x * y))
76 | part1 : String -> IO (String, ())
79 | sum . map (\(x,y) => x * y) . justMatches $
80 | asDisjointMatches Mul str True
81 | pure (show matches, ())
84 | part2 : () -> String -> IO String
89 | asDisjointMatches CmdR str True
90 | in pure (show matches)