1
0
Fork 0
advent-of-code/2020/07/day7.hs
Sloane Perrault 9b6f69483a dnf: day 7
2022-09-21 09:19:52 -04:00

75 lines
1.4 KiB
Haskell

module Day7 where
import Data.Char
import Text.ParserCombinators.ReadP
letter = satisfy isLetter
space = satisfy isSpace
digit = satisfy isDigit
parse p s = parsedResult $ readP_to_S p s
where
parsedResult [(a, "")] = a
parsedResult [(_, rs)] = error "Parser did not consume entire stream."
parsedResult (a:as) = parsedResult as
parsedResult _ = error "Parser error"
data Bag = Bag { name :: String }
deriving (Show)
bagName :: ReadP String
bagName = many1 (letter +++ space)
bag :: ReadP Bag
bag = do
name' <- bagName
_ <- space
_ <- string "bags" <++ string "bag"
return (Bag name')
int :: ReadP Int
int = do
digits <- many1 digit
return $ read digits
data Numbered a = Numbered { item :: a, value :: Int }
deriving (Show)
numberedBag :: ReadP (Numbered Bag)
numberedBag = do
value' <- int
_ <- space
bag' <- bag
return (Numbered bag' value')
data Rule = Rule { container :: Bag, contents :: [Numbered Bag] }
deriving (Show)
noOtherBags :: ReadP [Numbered Bag]
noOtherBags = do
_ <- string "no other bags"
return []
comma :: ReadP String
comma = string ", "
rule :: ReadP Rule
rule = do
container' <- bag
_ <- space
_ <- string "contain"
_ <- space
contents' <- noOtherBags <++ (numberedBag `sepBy1` comma)
return (Rule container' contents')
period = char '.'
endRule :: ReadP ()
endRule = do
_ <- period
skipSpaces
return ()
rules :: ReadP [Rule]
rules = rule `endBy1` endRule