Repetición cíclica
Definir la función
ciclica :: [a] -> [a]
tal que (ciclica xs) es la lista obtenida repitiendo cíclicamente los elementos de xs. Por ejemplo,
take 10 (ciclica [3,5]) == [3,5,3,5,3,5,3,5,3,5] take 10 (ciclica [3,5,7]) == [3,5,7,3,5,7,3,5,7,3] take 10 (ciclica [3,5..]) == [3,5,7,9,11,13,15,17,19,1] ciclica [] == []
Comprobar con QuickCheck que la función ciclica es equivalente a la predefinida cycle; es decir, para cualquier número entero n y cualquier lista no vacía xs, se verifica que
take n (ciclica xs) == take n (cycle xs)
Nota. Al hacer la comprobación limitar el tamaño de las pruebas como se indica a continuación
λ> quickCheckWith (stdArgs {maxSize=7}) prop_ciclica +++ OK, passed 100 tests.
Soluciones
import Test.QuickCheck -- 1ª definición ciclica1 :: [a] -> [a] ciclica1 [] = [] ciclica1 xs = xs ++ ciclica1 xs -- 2ª definición ciclica2 :: [a] -> [a] ciclica2 [] = [] ciclica2 xs = xs' where xs' = xs ++ xs' -- Comprobación de eficiencia -- λ> last (take 10000000 (ciclica1 [1,2])) -- 2 -- (3.69 secs, 1521758928 bytes) -- -- λ> last (take 10000000 (ciclica2 [1,2])) -- 2 -- (0.21 secs, 561468144 bytes) -- La 2ª definición es más eficiente. -- La propiedad es prop_ciclica :: Int -> [Int] -> Property prop_ciclica n xs = not (null xs) ==> take n (ciclica2 xs) == take n (cycle xs) -- La comprobación es -- λ> quickCheckWith (stdArgs {maxSize=7}) prop_ciclica -- +++ OK, passed 100 tests.