3 import Data.Text (Text)
4 import qualified Data.Text.IO as TIO
6 import Data.Void (Void)
8 import Text.Megaparsec hiding (State)
9 import Text.Megaparsec.Char
10 import qualified Text.Megaparsec.Char.Lexer as L
11 import qualified Control.Applicative as CA
18 } deriving (Show, Eq, Ord)
22 do text <- TIO.readFile "data/advent02.txt"
23 let policies = successfulParse text
24 print $ part1 policies
25 print $ part2 policies
27 part1 = length . filter inRange
28 where nCharsPresent p = length $ filter (== (character p)) (password p)
29 inRange p = (nCharsPresent p >= (lower p)) && (nCharsPresent p <= (upper p))
31 part2 = length . filter matches
33 matches p = ((pw!!l) == c) /= ((pw!!u) == c)
40 -- Parse the input file
41 type Parser = Parsec Void Text
44 sc = L.space space1 CA.empty CA.empty
45 -- sc = L.space (skipSome (char ' ')) CA.empty CA.empty
48 integerP = lexeme L.decimal
49 -- signedInteger = L.signed sc integer
53 characterP = alphaNumChar <* sc
54 passwordP = some alphaNumChar <* sc
56 policiesP = many policyP
57 policyP = Policy <$> integerP <* hyphenP <*> integerP <*> characterP <* colonP <*> passwordP
59 successfulParse :: Text -> [Policy]
60 successfulParse input =
61 case parse policiesP "input" input of
62 Left _err -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err
63 Right policies -> policies