Ir al contenido principal

Rompecabeza matemático

Definir una función

f :: Int -> Int

tal que para todo n, f(f(n)) = -n y comprobar con QuickCheck que se cumple la propiedad

prop_f :: Int -> Bool
prop_f n = f (f n) == -n

es decir,

λ> quickCheck prop_f
+++ OK, passed 100 tests.

Soluciones

-- 1ª definición (por casos)
f :: Int -> Int
f n | even n && n > 0 = n-1
    | even n && n < 0 = n+1
    | odd  n && n > 0 = -n-1
    | odd  n && n < 0 = -n+1
    | otherwise       = 0

-- La propiedad es
prop_f :: Int -> Bool
prop_f n = f (f n) == -n

-- La comprobación es
--    λ> quickCheck prop_f
--    +++ OK, passed 100 tests.

-- 2ª definición (por casos y signo):
f2 :: Int -> Int
f2 n | even n    =  n - signum n
     | odd  n    = -n - signum n
     | otherwise = 0

-- La propiedad es
prop_f2 :: Int -> Bool
prop_f2 n = f2 (f2 n) == -n

-- La comprobación es
--    λ> quickCheck prop_f2
--    +++ OK, passed 100 tests.

-- 3ª solución (sin casos):
f3 :: Int -> Int
f3 n = n * (2 * mod n 2 - 1) + signum n

-- La propiedad es
prop_f3 :: Int -> Bool
prop_f3 n = f3 (f3 n) == -n

-- La comprobación es
--    λ> quickCheck prop_f3
--    +++ OK, passed 100 tests.

-- 4ª solución (sin casos):
f4 :: Int -> Int
f4 n = (-1)^(abs n)*n - signum n

-- La propiedad es
prop_f4 :: Int -> Bool
prop_f4 n = f4 (f4 n) == -n

-- La comprobación es
--    λ> quickCheck prop_f4
--    +++ OK, passed 100 tests.