.
[aoc20.git] / 18 / one.icl
diff --git a/18/one.icl b/18/one.icl
new file mode 100644 (file)
index 0000000..9d890e3
--- /dev/null
@@ -0,0 +1,38 @@
+module one
+
+import StdEnv
+import Data.Either
+import Data.Func
+import Data.Functor
+import Control.Applicative
+import Control.Monad
+import Text.Parsers.Simple.ParserCombinators
+
+read :: *File -> [[Char]]
+read f
+       # (l, f) = freadline f
+       | l.[size l - 1] <> '\n' = []
+       = [[c\\c<-:l | c <> '\n']:read f]
+
+Start w
+       # (io, w) = stdio w
+       # ls = read io
+       = (one ls, two ls)
+
+one = fmap sum o sequence o map (parse pExpr)
+two = fmap sum o sequence o map (parse pExpr`)
+
+pExpr :: Parser Char Int
+pExpr = flip pChainl1 (pOp (+) '+' <|> pOp (*) '*') $ pInt <|> (pPOpen *> pExpr <* pPClose)
+
+pExpr` :: Parser Char Int
+pExpr`
+       = flip pChainl1 (pOp (*) '*')
+       $ flip pChainl1 (pOp (+) '+')
+       $ pInt <|> (pPOpen *> pExpr` <* pPClose)
+
+pOp :: (Int Int -> Int) Char -> Parser Char (Int Int -> Int)
+pOp op c = op <$ pSpace <* pToken c <* pSpace
+
+pInt :: Parser Char Int
+pInt = toInt o toString <$> some pDigit