|
- data Password = Password Int Int Char String
- deriving Show
-
- main :: IO ()
- main = do
- raw <- readFile "day2.txt"
- let ls = map parse $ lines raw
- fs = case (sequence ls) of
- Nothing -> error "invalid input"
- (Just ps) -> ps
- ansA = length $ filter (== True) $ map validA fs
- ansB = length $ filter (== True) $ map validB fs
- in do
- putStrLn $ "day2a: " ++ (show ansA)
- putStrLn $ "day2b: " ++ (show ansB)
-
- validA :: Password -> Bool
- validA (Password l u t p) =
- let len = length $ filter (== t) p
- in (len >= l)
- && (len <= u)
-
- validB :: Password -> Bool
- validB (Password a' b' t p) =
- case (inBounds a b p) of
- (False,False) -> False
- (True,False) -> (p !! a) == t
- (False,True) -> (p !! b) == t
- _ -> ((p !! a) == t) /= ((p !! b) == t)
- where
- a = (pred a')
- b = (pred b')
-
- parse :: String -> Maybe Password
- parse [] = Nothing
- parse s =
- do (l,s') <- parseInt s
- (u,s'') <- parseInt $ dropChar s'
- (t,s''') <- parseChar $ dropChar s''
- let p = (dropChar . dropChar) s'''
- in Just $ Password l u t p
-
- parseInt :: String -> Maybe (Int,String)
- parseInt s = case (reads s) of
- [] -> Nothing
- [a] -> Just a
-
- parseChar :: String -> Maybe (Char,String)
- parseChar [] = Nothing
- parseChar (t:s) = Just (t,s)
-
- dropChar :: String -> String
- dropChar [] = []
- dropChar (_:ls) = ls
-
- inBounds :: Int -> Int -> String -> (Bool, Bool)
- inBounds a b s = ( len >= a, len >= b )
- where len = length s
|