Last active
December 19, 2020 23:18
-
-
Save ddellacosta/fea546b5c0af4f5cd3721e4292342ec0 to your computer and use it in GitHub Desktop.
Advent of Code Day 18 solution in Haskell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE LambdaCase #-} | |
module Day18_2 where | |
import Data.Text as T | |
import Data.Void | |
import System.IO | |
import Text.Megaparsec | |
import Text.Megaparsec.Char | |
import qualified Text.Megaparsec.Char.Lexer as L | |
import Control.Monad.Reader | |
import Text.Pretty.Simple | |
data Part = One | Two | |
deriving (Show) | |
data Opts = Opts | |
{ part :: Part } | |
deriving (Show) | |
type Parser = ParsecT Void Text (Reader Opts) | |
parseOp1 :: Int -> Int -> (Int -> Parser Int) -> Char -> Parser Int | |
parseOp1 d1 d2 p = \case | |
'+' -> p (d1 + d2) | |
'*' -> p (d1 * d2) | |
parseOp2 :: Int -> Int -> (Int -> Parser Int) -> Char -> Parser Int | |
parseOp2 d1 d2 p = \case | |
'+' -> p (d1 + d2) | |
'*' -> (p d2) >>= pure . (d1 *) | |
termBody :: Int -> Parser Int | |
termBody d1 = do | |
op <- (char '+' <|> char '*') | |
space | |
d2 <- (L.decimal :: Parser Int) <|> subTerm | |
space | |
opts <- ask | |
let opParseFn = case (part opts) of | |
One -> parseOp1 | |
Two -> parseOp2 | |
opParseFn d1 d2 termBody op <|> opParseFn d1 d2 pure op | |
subTerm :: Parser Int | |
subTerm = between (char '(') (char ')') term | |
term :: Parser Int | |
term = do | |
d1 <- (L.decimal :: Parser Int) <|> subTerm | |
space | |
termBody d1 | |
terms :: Parser Int | |
terms = sum <$> manyTill term eof | |
main :: Part -> FilePath -> IO () | |
main part file = withFile file ReadMode | |
(\fh -> do | |
contents <- hGetContents fh | |
pPrint $ ((flip runReader (Opts part)) . (runParserT terms "") . T.pack) contents) | |
-- e.g. | |
λ> main One "/home/dd/code/launchpad/day18-input.txt" | |
Right 6640667297513 | |
λ> main Two "/home/dd/code/launchpad/day18-input.txt" | |
Right 451589894841552 | |
λ> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment