[hs] Solve 2020_19 part 1

This commit is contained in:
Joscha 2020-12-19 15:53:27 +00:00
parent 7db29cd79b
commit e8f3e01617
4 changed files with 79 additions and 3 deletions

View file

@ -11,6 +11,7 @@ module Aoc.Parse
, lineSatisfy , lineSatisfy
, line , line
, lineChar , lineChar
, lineSpace
, word , word
, digit , digit
) where ) where
@ -67,6 +68,9 @@ line = lineWhile (const True)
lineChar :: Parser Char lineChar :: Parser Char
lineChar = lineSatisfy (const True) lineChar = lineSatisfy (const True)
lineSpace :: Parser T.Text
lineSpace = lineWhile isSpace
word :: Parser T.Text word :: Parser T.Text
word = takeWhileP (Just "alphanumeric character") isAlphaNum word = takeWhileP (Just "alphanumeric character") isAlphaNum

View file

@ -21,6 +21,7 @@ import qualified Aoc.Y2020.D15 as D15
import qualified Aoc.Y2020.D16 as D16 import qualified Aoc.Y2020.D16 as D16
import qualified Aoc.Y2020.D17 as D17 import qualified Aoc.Y2020.D17 as D17
import qualified Aoc.Y2020.D18 as D18 import qualified Aoc.Y2020.D18 as D18
import qualified Aoc.Y2020.D19 as D19
year :: Year year :: Year
year = Year 2020 year = Year 2020
@ -42,4 +43,5 @@ year = Year 2020
, (16, D16.day) , (16, D16.day)
, (17, D17.day) , (17, D17.day)
, (18, D18.day) , (18, D18.day)
, (19, D19.day)
] ]

View file

@ -5,7 +5,6 @@ module Aoc.Y2020.D18
) where ) where
import Control.Monad import Control.Monad
import Data.Char
import Control.Monad.Combinators.Expr import Control.Monad.Combinators.Expr
import qualified Data.Text as T import qualified Data.Text as T
@ -15,10 +14,10 @@ import Aoc.Day
import Aoc.Parse import Aoc.Parse
lexeme :: Parser a -> Parser a lexeme :: Parser a -> Parser a
lexeme = L.lexeme (void $ lineWhile isSpace) lexeme = L.lexeme (void lineSpace)
symbol :: T.Text -> Parser T.Text symbol :: T.Text -> Parser T.Text
symbol = L.symbol (void $ lineWhile isSpace) symbol = L.symbol (void lineSpace)
parser :: [[Operator Parser Int]] -> Parser [Int] parser :: [[Operator Parser Int]] -> Parser [Int]
parser table = manyLines expr parser table = manyLines expr

71
hs/src/Aoc/Y2020/D19.hs Normal file
View file

@ -0,0 +1,71 @@
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
module Aoc.Y2020.D19
( day
) where
import Control.Monad
import Data.Foldable
import Control.Monad.Trans.Class
import Control.Monad.Trans.State
import qualified Data.Map as Map
import qualified Data.Text as T
import qualified Text.Megaparsec.Char.Lexer as L
import Aoc.Day
import Aoc.Parse
data Rule = Leaf Char | Branch [[Int]]
deriving (Show)
type Rules = Map.Map Int Rule
lexeme :: Parser a -> Parser a
lexeme = L.lexeme (void lineSpace)
symbol :: T.Text -> Parser T.Text
symbol = L.symbol (void lineSpace)
parser :: Parser (Rules, [String])
parser = do
rules <- Map.fromList <$> many (rule <* newline)
void newline
msgs <- map T.unpack <$> manyLines line
pure (rules, msgs)
where
leaf = Leaf <$> (char '"' *> lineChar <* char '"')
branch = Branch <$> some (lexeme decimal) `sepBy1` symbol "|"
rule = do
name <- decimal <* symbol ":"
content <- leaf <|> branch
pure (name, content)
type SolveM = StateT String []
consume :: Char -> SolveM ()
consume c = get >>= \case
(x:xs) | x == c -> put xs
_ -> empty
apply :: Rules -> Int -> SolveM ()
apply rules ruleId = case rules Map.! ruleId of
Leaf c -> consume c
Branch options -> traverse_ (apply rules) =<< lift options
applyFully :: Rules -> Int -> SolveM ()
applyFully rules ruleId = do
apply rules ruleId
guard . null =<< get
isValid :: Rules -> String -> Bool
isValid rules msg = not $ null $ runStateT (applyFully rules 0) msg
solver :: (Rules, [String]) -> IO ()
solver (rules, msgs) = do
putStrLn ">> Part 1"
print $ length $ filter (isValid rules) msgs
day :: Day
day = dayParse parser solver