You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

59 lines
1.5KB

  1. data Password = Password Int Int Char String
  2. deriving Show
  3. main :: IO ()
  4. main = do
  5. raw <- readFile "day2.txt"
  6. let ls = map parse $ lines raw
  7. fs = case (sequence ls) of
  8. Nothing -> error "invalid input"
  9. (Just ps) -> ps
  10. ansA = length $ filter (== True) $ map validA fs
  11. ansB = length $ filter (== True) $ map validB fs
  12. in do
  13. putStrLn $ "day2a: " ++ (show ansA)
  14. putStrLn $ "day2b: " ++ (show ansB)
  15. validA :: Password -> Bool
  16. validA (Password l u t p) =
  17. let len = length $ filter (== t) p
  18. in (len >= l)
  19. && (len <= u)
  20. validB :: Password -> Bool
  21. validB (Password a' b' t p) =
  22. case (inBounds a b p) of
  23. (False,False) -> False
  24. (True,False) -> (p !! a) == t
  25. (False,True) -> (p !! b) == t
  26. _ -> ((p !! a) == t) /= ((p !! b) == t)
  27. where
  28. a = (pred a')
  29. b = (pred b')
  30. parse :: String -> Maybe Password
  31. parse [] = Nothing
  32. parse s =
  33. do (l,s') <- parseInt s
  34. (u,s'') <- parseInt $ dropChar s'
  35. (t,s''') <- parseChar $ dropChar s''
  36. let p = (dropChar . dropChar) s'''
  37. in Just $ Password l u t p
  38. parseInt :: String -> Maybe (Int,String)
  39. parseInt s = case (reads s) of
  40. [] -> Nothing
  41. [a] -> Just a
  42. parseChar :: String -> Maybe (Char,String)
  43. parseChar [] = Nothing
  44. parseChar (t:s) = Just (t,s)
  45. dropChar :: String -> String
  46. dropChar [] = []
  47. dropChar (_:ls) = ls
  48. inBounds :: Int -> Int -> String -> (Bool, Bool)
  49. inBounds a b s = ( len >= a, len >= b )
  50. where len = length s