Done day 18
[advent-of-code-20.git] / advent18 / src / advent18.hs
1 -- import Debug.Trace
2
3 import Data.Text (Text)
4 -- import qualified Data.Text as T
5 import qualified Data.Text.IO as TIO
6
7 import Data.Attoparsec.Text hiding (take)
8 -- import Data.Attoparsec.Combinator
9 import Control.Applicative
10 -- import Control.Applicative.Combinators
11
12 data Expression
13 = Number Integer
14 | Mul Expression Expression
15 | Add Expression Expression
16 deriving (Show, Eq)
17
18
19 main :: IO ()
20 main =
21 do text <- TIO.readFile "data/advent18.txt"
22 print $ part1 text
23 print $ part2 text
24
25
26 part1 = parseAndEval expressionsP
27 part2 = parseAndEval pExpressionsP
28
29 parseAndEval parser text = sumEval $ successfulParse parser text
30
31 sumEval = sum . map evaluate
32
33 showE (Number x) = show x
34 showE (Mul a b) = "(" ++ showE a ++ " * " ++ showE b ++ ")"
35 showE (Add a b) = "(" ++ showE a ++ " + " ++ showE b ++ ")"
36
37 evaluate (Number x) = x
38 evaluate (Mul a b) = (evaluate a) * (evaluate b)
39 evaluate (Add a b) = (evaluate a) + (evaluate b)
40
41
42 -- Parse the input file
43
44 numberP = Number <$> decimal
45 mulExprP = string " * " *> pure Mul
46 addExprP = string " + " *> pure Add
47
48
49 -- Part 1 parsing
50
51 expressionsP = exprP `sepBy` endOfLine
52
53 exprP = elementP `chainl1` (mulExprP <|> addExprP)
54
55 elementP = numberP <|> bracketedP
56 bracketedP = "(" *> exprP <* ")"
57
58
59 -- Part 2 parsing
60
61 pExpressionsP = pExprP `sepBy` endOfLine
62
63 pExprP = pTermP `chainl1` mulExprP
64 pTermP = pElementP `chainl1` addExprP
65
66 pElementP = numberP <|> pBracketedP
67 pBracketedP = "(" *> pExprP <* ")"
68
69
70 -- chainl1 :: Parser a -> Parser (a -> a -> a) -> Parser a
71 -- chainl1 p op = p >>= rest
72 -- where
73 -- rest a = (do
74 -- f <- op
75 -- b <- p
76 -- rest (f a b)) <|> pure a
77
78
79 chainl1 :: Parser a -> Parser (a -> a -> a) -> Parser a
80 p `chainl1` op = do a <- p
81 rest a
82 where rest a = (do f <- op
83 b <- p
84 rest (f a b))
85 <|> return a
86
87
88 -- successfulParse :: Text -> (Integer, [Maybe Integer])
89 successfulParse parser input =
90 case parseOnly parser input of
91 Left _err -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err
92 Right expressions -> expressions