Lista cuadrada
Definir la función
listaCuadrada :: Int -> a -> [a] -> [[a]]
tal que (listaCuadrada n x xs)
es una lista de n
listas de longitud n
formadas con los elementos de xs
completada con x
, si no xs
no tiene suficientes elementos. Por ejemplo,
listaCuadrada 3 7 [0,3,5,2,4] == [[0,3,5],[2,4,7],[7,7,7]] listaCuadrada 3 7 [0..] == [[0,1,2],[3,4,5],[6,7,8]] listaCuadrada 2 'p' "eva" == ["ev","ap"] listaCuadrada 2 'p' ['a'..] == ["ab","cd"]
1. Soluciones en Haskell
module Lista_cuadrada where import Data.List.Split (chunksOf) import Test.Hspec (Spec, describe, hspec, it, shouldBe) import Test.QuickCheck -- 1ª solución -- =========== listaCuadrada1 :: Int -> a -> [a] -> [[a]] listaCuadrada1 n x xs = take n (grupos n (xs ++ repeat x)) -- (grupos n xs) es la lista obtenida agrupando los elementos de xs en -- grupos de n elementos, salvo el último que puede tener menos. Por -- ejemplo, -- grupos 2 [4,2,5,7,6] == [[4,2],[5,7],[6]] -- take 3 (grupos 3 [1..]) == [[1,2,3],[4,5,6],[7,8,9]] grupos :: Int -> [a] -> [[a]] grupos _ [] = [] grupos n xs = take n xs : grupos n (drop n xs) -- 2ª solución -- =========== listaCuadrada2 :: Int -> a -> [a] -> [[a]] listaCuadrada2 n x xs = take n (grupos2 n (xs ++ repeat x)) grupos2 :: Int -> [a] -> [[a]] grupos2 _ [] = [] grupos2 n xs = ys : grupos n zs where (ys,zs) = splitAt n xs -- 3ª solución -- =========== listaCuadrada3 :: Int -> a -> [a] -> [[a]] listaCuadrada3 n x xs = take n (chunksOf n (xs ++ repeat x)) -- Verificación -- ============ verifica :: IO () verifica = hspec spec specG :: (Int -> Int -> [Int] -> [[Int]]) -> Spec specG listaCuadrada = do it "e1" $ listaCuadrada 3 7 [0,3,5,2,4] `shouldBe` [[0,3,5],[2,4,7],[7,7,7]] it "e2" $ listaCuadrada 3 7 [0..] `shouldBe` [[0,1,2],[3,4,5],[6,7,8]] spec :: Spec spec = do describe "def. 1" $ specG listaCuadrada1 describe "def. 2" $ specG listaCuadrada2 describe "def. 3" $ specG listaCuadrada3 -- La verificación es -- λ> verifica -- -- 6 examples, 0 failures -- Comprobación de la equivalencia -- =============================== -- La propiedad es prop_listaCuadrada :: Int -> Int -> [Int] -> Bool prop_listaCuadrada n x xs = all (== listaCuadrada1 n x xs) [listaCuadrada2 n x xs, listaCuadrada3 n x xs] -- La comprobación es -- λ> quickCheck prop_listaCuadrada -- +++ OK, passed 100 tests. -- Comparación de eficiencia -- ========================= -- La comparación es -- λ> length (listaCuadrada1 (10^4) 5 [1..]) -- 10000 -- (2.02 secs, 12,801,918,616 bytes) -- λ> length (listaCuadrada2 (10^4) 5 [1..]) -- 10000 -- (1.89 secs, 12,803,198,576 bytes) -- λ> length (listaCuadrada3 (10^4) 5 [1..]) -- 10000 -- (1.85 secs, 12,801,518,728 bytes)
2. Soluciones en Python y en Common Lisp
Las soluciones en Python y en Common Lisp de este problema se han añadido en la versión del 20 de febrero de 2025.