module Main where import Text.Parsec (parse, digit, char, string, anyChar, many, many1) import Input data Policy = Policy Int Int Char deriving (Show) parseLine :: String -> (Policy, String) parseLine str = case parse pLine "" str of Right r -> r ; Left e -> error (show e) where pLine = do n1 <- read <$> many1 digit _ <- char '-' n2 <- read <$> many1 digit _ <- char ' ' c <- anyChar _ <- string ": " s <- many anyChar return (Policy n1 n2 c, s) valid1 :: Policy -> String -> Bool valid1 (Policy l h c) pw = let count = length (filter (== c) pw) in l <= count && count <= h valid2 :: Policy -> String -> Bool valid2 (Policy l h c) pw = let c1 = pw !! (l - 1) ; c2 = pw !! (h - 1) in (c1 == c || c2 == c) && c1 /= c2 numValid :: (Policy -> String -> Bool) -> [(Policy, String)] -> Int numValid f = sum . map (fromEnum . uncurry f) main :: IO () main = do input <- map parseLine <$> getInput 2 print (numValid valid1 input) print (numValid valid2 input)