Repetición de elementos
Definir la función
repiteElementos :: Int -> [a] -> [a]
tal que (repiteElementos k xs) es la lista obtenida repitiendo k veces cada elemento de xs. Por ejemplo,
repiteElementos 3 [5,2,7,4] == [5,5,5,2,2,2,7,7,7,4,4,4]
Comprobar con QuickCheck que, para todo número natural k y toda lista xs, el número de elementos de (repiteElementos k xs) es k veces el número de elementos de xs.
Soluciones
import Test.Hspec (Spec, describe, hspec, it, shouldBe) import Test.QuickCheck -- 1ª solución -- =========== repiteElementos1 :: Int -> [a] -> [a] repiteElementos1 k xs = concat [replicate k x | x <- xs] -- 2ª solución -- =========== repiteElementos2 :: Int -> [a] -> [a] repiteElementos2 k xs = concat (map (replicate k) xs) -- 3ª solución -- =========== repiteElementos3 :: Int -> [a] -> [a] repiteElementos3 k = concatMap (replicate k) -- 4ª solución -- =========== repiteElementos4 :: Int -> [a] -> [a] repiteElementos4 _ [] = [] repiteElementos4 k (x:xs) = replicate k x ++ repiteElementos4 k xs -- 5ª solución -- =========== repiteElementos5 :: Int -> [a] -> [a] repiteElementos5 k = foldr ((++) . replicate k) [] -- Verificación -- ============ verifica :: IO () verifica = hspec spec specG :: (Int -> [Int] -> [Int]) -> Spec specG repiteElementos = do it "e1" $ repiteElementos 3 [5,2,7,4] `shouldBe` [5,5,5,2,2,2,7,7,7,4,4,4] spec :: Spec spec = do describe "def. 1" $ specG repiteElementos1 describe "def. 2" $ specG repiteElementos2 describe "def. 3" $ specG repiteElementos3 describe "def. 4" $ specG repiteElementos4 describe "def. 5" $ specG repiteElementos5 -- La verificación es -- λ> verifica -- 5 examples, 0 failures -- Comprobación de equivalencia -- ============================ -- La propiedad es prop_equivalencia :: Int -> [Int] -> Bool prop_equivalencia k xs = repiteElementos2 k xs == ys && repiteElementos3 k xs == ys && repiteElementos4 k xs == ys && repiteElementos5 k xs == ys where ys = repiteElementos1 k xs -- La comprobación es -- λ> quickCheckWith (stdArgs {maxSize=10}) prop_equivalencia -- +++ OK, passed 100 tests. -- Comparación de eficiencia -- ========================= -- La comparación es -- λ> length (repiteElementos1 10000 [1..10000]) -- 100000000 -- (1.28 secs, 11,202,762,144 bytes) -- λ> length (repiteElementos2 10000 [1..10000]) -- 100000000 -- (1.28 secs, 11,202,442,120 bytes) -- λ> length (repiteElementos3 10000 [1..10000]) -- 100000000 -- (1.26 secs, 11,201,562,128 bytes) -- λ> length (repiteElementos4 10000 [1..10000]) -- 100000000 -- (1.30 secs, 11,202,762,024 bytes) -- λ> length (repiteElementos5 10000 [1..10000]) -- 100000000 -- (1.33 secs, 11,202,202,208 bytes) -- Comprobación de la propiedad -- ============================ -- La propiedad es prop_repiteElementos :: NonNegative Int -> [Int] -> Bool prop_repiteElementos (NonNegative k) xs = length (repiteElementos1 k xs) == k * length xs -- La comprobación es -- λ> quickCheckWith (stdArgs {maxSize=7}) prop_repiteElementos -- +++ OK, passed 100 tests.