Ir al contenido principal

Mayor diferencia progresiva

La diferencia progresiva entre dos elementos de una lista es la resta entre el que ocupa la mayor posición y la menor. Por ejemplo, en la lista [1,5,8,2,9] la diferencia entre los elementos 5 y 8 es 3 y entre 5 y 2 es -3.

Definir la función

mayorDiferencia :: [Int] -> Int

tal que (mayorDiferencia xs) es la mayor diferencia progresiva entre los elementos de xs. Por ejemplo,

mayorDiferencia [1,5,8,2,9]  ==  8
mayorDiferencia [9,5,8,2,1]  ==  3
mayorDiferencia [3,2,1]      ==  0
mayorDiferencia [1..10^7]    ==  9999999

Soluciones

import Data.List (inits)

-- 1ª definición (por recursión):
mayorDiferencia :: [Int] -> Int
mayorDiferencia ([_])  = 0
mayorDiferencia (x:xs) =
    max (maximum [y-x | y <- xs]) (mayorDiferencia xs)

-- 2ª definición (por comprensión)
mayorDiferencia2 :: [Int] -> Int
mayorDiferencia2 xs =
    maximum [x-y | (x,y) <- zip xs (map minimum (tail (inits xs)))]

-- 3ª definición:
mayorDiferencia3 :: [Int] -> Int
mayorDiferencia3 xs = maximum (zipWith (-) xs (scanl1 min xs))

-- 4ª definición:
mayorDiferencia4 :: [Int] -> Int
mayorDiferencia4 xs = maximum . zipWith (-) xs $ scanl1 min xs

-- Comparación de eficiencia
--    λ> mayorDiferencia [1..3000]
--    2999
--    (3.43 secs, 943439560 bytes)
--
--    λ> mayorDiferencia2 [1..3000]
--    2999
--    (3.38 secs, 978359192 bytes)
--
--    λ> mayorDiferencia3 [1..3000]
--    2999
--    (0.01 secs, 2877960 bytes)
--
--    λ> mayorDiferencia4 [1..3000]
--    2999
--    (0.01 secs, 2062616 bytes)