module Main where import Text.ParserCombinators.Parsec import Text.Parsec.Char countElem c ls = sum $ map (fromEnum . (== c)) ls xor a b = (not a && b) || (a && not b) right (Right a) = a data PassProp = PassProp { range :: (Int, Int) , c :: Char , pass :: String } deriving (Show) parseProp :: Parser PassProp parseProp = do lower <- many1 digit upper <- char '-' >> many1 digit c <- space >> letter password <- string ": " >> many letter return $ PassProp (read lower, read upper) c password doCheck1 :: PassProp -> Bool doCheck1 PassProp { range = (lower, upper), c = c, pass = pass} = count >= lower && count <= upper where count = countElem c pass doCheck2 :: PassProp -> Bool doCheck2 PassProp { range = (lower, upper), c = c, pass = pass} = (pass !! (lower - 1) == c) `xor` (pass !! (upper - 1) == c) parseLine :: Parser a -> String -> a parseLine parser line = right $ parse parser "input" line main :: IO () main = do n <- map (parseLine parseProp) . lines <$> readFile "input/02" print $ countElem True (map doCheck1 n) print $ countElem True (map doCheck2 n)