blob: e77ea485ac25ac311250d0b772636732b69f2c2e (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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))
|