import Test.QuickCheck basic :: Int -> [Int] -> Bool basic _ [] = True basic _ [h] = True basic s (h1 : hs@(h2 : _)) = (r <= s') && basic (s' - (if (-r) > s' then 1 else 0)) hs where r = h2 - h1 s' = max 0 s f :: Int -> [Int] -> Bool f _[_]=True;f s(h:j@(i:_))=(i-h<=s)&&f(max 0$s-fromEnum((h-i)>s))j cases :: [((Int, [Int]), Bool, String)] cases = [ -- Truthy What is this testing? ((0, [1,1,1,1,1]), True, "Flat terrain with 0 stamina"), ((0, [50,45,20,19,18,10,1,1,1]), True, "Drops with 0 stamina"), ((5, [1,6,11,16,21,26,31]), True, "Arduous climb, barely doable"), ((100, [500,1,100]), True, "Long drop, strong climber"), ((45, [20,50]), True, "Short trek, excess stamina"), ((4, [6,2,1,2,5,6,1,2,3,5,1,1,1,3]), True, "Example with a shorter cliff at the end"), ((17, [59,61,47,64,23,34,21,22,25,29,25]), True, "Randomly generated"), -- Falsy What is this testing? ((4, [6,2,1,2,5,6,1,2,3,5,1,1,1,4]), False, "Example"), ((0, [1,1,2,1,1]), False, "Small hill with no stamina"), ((5, [30,28,22,18,13,9,7,9,11,14,22,23]), False, "Valley with too many drops"), ((6, [40,47,49,55,61,66,69,70,50,55]), False, "Early failure"), ((45, [79,48,41,70,76,85,27,12,31,66,13,17,94,77]), False, "Randomly generated"), ((31, [65,21,20,32,9,9,37,14,23,19,32,63]), False, "Randomly generated") ] testCase :: (Eq b) => (a -> b) -> (a, b, String) -> String testCase f (args, ans, name) = if ans == f args then "." else "Failed \"" ++ name ++ "\"" main :: IO () main = do print $ testCase (uncurry f) <$> cases quickCheck (\(s, h1, hs) -> let s' = abs s hs' = abs <$> h1 : hs in basic s' hs' == f s' hs')