diff --git a/2023/haskell/aoc2023.cabal b/2023/haskell/aoc2023.cabal index a590f08..34d7f08 100644 --- a/2023/haskell/aoc2023.cabal +++ b/2023/haskell/aoc2023.cabal @@ -31,6 +31,7 @@ library Day11 Day12 Day15 + Day20 Day24 other-modules: diff --git a/2023/haskell/solutions/Day20.hs b/2023/haskell/solutions/Day20.hs new file mode 100644 index 0000000..de5c185 --- /dev/null +++ b/2023/haskell/solutions/Day20.hs @@ -0,0 +1,57 @@ +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RecordWildCards #-} +module Day20 where + +import Data.Void (Void) +import Data.Text (Text) +import Data.Bifunctor (first) +import Text.Megaparsec (Parsec, (<|>), errorBundlePretty, runParser, eof, many, choice, sepBy) +import Text.Megaparsec.Char (char, alphaNumChar, space, string) +import Text.Megaparsec.Char.Lexer () + + +data ModType + = Cast -- Broadcast + | Flip -- Flip-Flop + | Conj -- Conjuntion + deriving Show + +data Mod = Mod + { mName :: !String + , mType :: !ModType + , mNext :: ![String] + } deriving Show + +type Parser = Parsec Void Text + +a :: Text +a = + "broadcaster -> a, b, c\n\ + \%a -> b\n\ + \%b -> c\n\ + \%c -> inv\n\ + \&inv -> a\n" + +b :: Text +b = + "broadcaster -> a\n\ + \%a -> inv, con\n\ + \&inv -> b\n\ + \%b -> con\n\ + \&con -> output\n" + +parse :: Text -> Either String [Mod] +parse = first errorBundlePretty . runParser ms "" + where + m :: Parser Mod + m = do + mType <- choice [ Flip <$ char '%', Conj <$ char '&' ] <|> pure Cast + mName <- many alphaNumChar <* space <* string "->" <* space + mNext <- (many alphaNumChar `sepBy` string ", ") <* space + return $ Mod {..} + ms :: Parser [Mod] + ms = many m <* eof + +-- >>> parse a +-- Right [Mod {mName = "broadcaster", mType = Cast, mNext = ["a","b","c"]},Mod {mName = "a", mType = Flip, mNext = ["b"]},Mod {mName = "b", mType = Flip, mNext = ["c"]},Mod {mName = "c", mType = Flip, mNext = ["inv"]},Mod {mName = "inv", mType = Conj, mNext = ["a"]}] +