diff options
Diffstat (limited to '2020/18.hs')
-rw-r--r-- | 2020/18.hs | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/2020/18.hs b/2020/18.hs new file mode 100644 index 0000000..e77ea48 --- /dev/null +++ b/2020/18.hs @@ -0,0 +1,39 @@ +module Main where + +import Text.Parsec hiding (getInput) +import Text.Parsec.Expr + +import Input + + +data Expr = Expr :+ Expr | Expr :* Expr | Lit Int + deriving (Show) + +eval :: Expr -> Int +eval (a :+ b) = eval a + eval b +eval (a :* b) = eval a * eval b +eval (Lit n) = n + +type Parser = Parsec String () + +data Part = Part1 | Part2 + +parseExpr :: Part -> String -> Expr +parseExpr part = either (error . show) id . parse pExpr "" + where + pExpr = buildExpressionParser (table part) pTerm + table Part1 = [[Infix (pOpers [pOperPlus, pOperMul]) AssocLeft]] + table Part2 = [[Infix (pOpers [pOperPlus]) AssocLeft] + ,[Infix (pOpers [pOperMul]) AssocLeft]] + pTerm = try (spaces >> ((Lit <$> pNum) <|> pParens)) + pNum = read <$> many1 digit + pParens = between (char '(') (char ')') pExpr + pOpers os = try (spaces >> choice os) :: Parser (Expr -> Expr -> Expr) + pOperPlus = (:+) <$ char '+' + pOperMul = (:*) <$ char '*' + +main :: IO () +main = do + input <- getInput 18 + print (sum (map (eval . parseExpr Part1) input)) + print (sum (map (eval . parseExpr Part2) input)) |