Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- fastSolve :: [Int] -> Bool
- fastSolve xs = interpret (accSolve Nothing Nothing Nothing Nothing xs)
- rEven, rOdd, rSmall :: Int -> Bool
- rEven x = x `mod` 2 == 0
- rOdd x = x > 0 && x `mod` 2 == 1
- rSmall x = 5 <= x && x <= 10
- -- shortcut for types
- type M a = Maybe a
- accSolve :: M Int -> M Int -> M Int -> M Int -> [Int] -> (M Int, M Int, M Int, M Int)
- accSolve sE sO bE bO [] = (sE,sO,bE,bO)
- accSolve sE sO bE bO (x:xs) = case (rSmall x, rEven x, rOdd x) of
- (True, True, False) -> case sE of
- Nothing -> accSolve (Just x) sO bE bO xs
- (Just y) -> accSolve sE sO (Just x) bO xs
- (True, False, True) -> case sO of
- Nothing -> accSolve sE (Just x) bE bO xs
- (Just y) -> accSolve sE sO bE (Just x) xs
- (False, True, False) -> accSolve sE sO (Just x) bO xs
- (False, False, True) -> accSolve sE sO bE (Just x) xs
- (False, False, False) -> accSolve sE sO bE bO xs
- interpret :: (M Int , M Int , M Int , M Int ) -> Bool
- interpret (Just jsE, _ , Just jbE, Just jbO) = True
- interpret (_ , Just jsO, Just jbE, Just jbO) = True
- interpret (Just jsE, Just jsO, _ , Just jbO) = True
- interpret (Just jsE, Just jsO, Just jbE, _ ) = True
- interpret (_ , _ , _ , _ ) = False
- {-
- This exploits the fact that any number that satisfies rSmall will either
- satisfy rOdd or rEven.
- We use four accumulators abbreviated for convenience:
- - smallEven
- - smallOdd
- - bigEven
- - bigOdd
- small means the number is inside [5,10]
- big means the number is NOT inside [5,10]
- even is obvious
- odd refers to those positive and odd
- Numbers that don't meet any of these are irrelevant so we can throw them away.
- We have to hold on to two numbers in [5,10] (nicknamed small) because
- at the end we could need either to fill in for it's more general
- trait. Look at how `interpret` handles cases with both smalls filled.
- -}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement