Done day 2
[advent-of-code-20.git] / advent02 / src / advent02.hs
1 -- import Debug.Trace
2
3 import Data.Text (Text)
4 import qualified Data.Text.IO as TIO
5
6 import Data.Void (Void)
7
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
12
13 data Policy = Policy
14 { lower :: Int
15 , upper :: Int
16 , character :: Char
17 , password :: String
18 } deriving (Show, Eq, Ord)
19
20 main :: IO ()
21 main =
22 do text <- TIO.readFile "data/advent02.txt"
23 let policies = successfulParse text
24 print $ part1 policies
25 print $ part2 policies
26 -- print $ head $ part2 nums
27
28 part1 = length . filter inRange
29 where nCharsPresent p = length $ filter (== (character p)) (password p)
30 inRange p = (nCharsPresent p >= (lower p)) && (nCharsPresent p <= (upper p))
31
32 part2 = length . filter matches
33
34 matches p = ((pw!!l) == c) /= ((pw!!u) == c)
35 where pw = password p
36 c = character p
37 l = (lower p) - 1
38 u = (upper p) - 1
39
40
41 -- Parse the input file
42 type Parser = Parsec Void Text
43
44 sc :: Parser ()
45 sc = L.space (skipSome spaceChar) CA.empty CA.empty
46 -- sc = L.space (skipSome (char ' ')) CA.empty CA.empty
47
48 lexeme = L.lexeme sc
49 integerP = lexeme L.decimal
50 -- signedInteger = L.signed sc integer
51 symb = L.symbol sc
52 hyphenP = symb "-"
53 colonP = symb ":"
54 characterP = alphaNumChar <* sc
55 passwordP = some alphaNumChar <* sc
56
57 policiesP = many policyP
58 policyP = Policy <$> integerP <* hyphenP <*> integerP <*> characterP <* colonP <*> passwordP
59 -- policyP = (,,,) <$> integerP <* hyphenP <*> integerP <*> characterP <* colonP <*> passwordP
60
61 -- successfulParse :: Text -> [Policy]
62 successfulParse input =
63 case parse policiesP "input" input of
64 Left _err -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err
65 Right policies -> policies