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))