La semana en Exercitium (del 4 al 8 de abril)
Esta semana he publicado en Exercitium las soluciones de los siguientes problemas:
- 1. Mayor producto de las ramas de un árbol
- 2. Diferencia simétrica
- 3. Conjunto de primos relativos
- 4. Familias de números con algún dígito en común
- 5. Biparticiones de una lista
A continuación se muestran las soluciones.
1. Mayor producto de las ramas de un árbol
Los árboles se pueden representar mediante el siguiente tipo de datos
1 2 |
data Arbol a = N a [Arbol a] deriving Show |
Por ejemplo, los árboles
1 2 3 4 5 6 |
1 3 / \ /|\ 2 3 / | \ | 5 4 7 4 | /\ 6 2 1 |
se representan por
1 2 3 |
ej1, ej2 :: Arbol Int ej1 = N 1 [N 2 [],N 3 [N 4 []]] ej2 = N 3 [N 5 [N 6 []], N 4 [], N 7 [N 2 [], N 1 []]] |
Definir la función
1 |
mayorProducto :: (Ord a, Num a) => Arbol a -> a |
tal que (mayorProducto a)
es el mayor producto de las ramas del árbol a
. Por ejemplo,
1 2 3 4 5 6 7 8 9 10 11 12 13 |
λ> mayorProducto (N 1 [N 2 [], N 3 []]) 3 λ> mayorProducto (N 1 [N 8 [], N 4 [N 3 []]]) 12 λ> mayorProducto (N 1 [N 2 [],N 3 [N 4 []]]) 12 λ> mayorProducto (N 3 [N 5 [N 6 []], N 4 [], N 7 [N 2 [], N 1 []]]) 90 λ> mayorProducto (N (-8) [N 0 [N (-9) []],N 6 []]) 0 λ> a = N (-4) [N (-7) [],N 14 [N 19 []],N (-1) [N (-6) [],N 21 []],N (-4) []] λ> mayorProducto a 84 |
Soluciones
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
import Test.QuickCheck data Arbol a = N a [Arbol a] deriving Show -- 1ª solución -- =========== mayorProducto1 :: (Ord a, Num a) => Arbol a -> a mayorProducto1 a = maximum [product xs | xs <- ramas a] -- (ramas a) es la lista de las ramas del árbol a. Por ejemplo, -- λ> ramas (N 3 [N 5 [N 6 []], N 4 [], N 7 [N 2 [], N 1 []]]) -- [[3,5,6],[3,4],[3,7,2],[3,7,1]] ramas :: Arbol b -> [[b]] ramas (N x []) = [[x]] ramas (N x as) = [x : xs | a <- as, xs <- ramas a] -- 2ª solución -- =========== mayorProducto2 :: (Ord a, Num a) => Arbol a -> a mayorProducto2 a = maximum (map product (ramas a)) -- 3ª solución -- =========== mayorProducto3 :: (Ord a, Num a) => Arbol a -> a mayorProducto3 = maximum . map product . ramas -- 4º solución -- =========== mayorProducto4 :: (Ord a, Num a) => Arbol a -> a mayorProducto4 = maximum . productosRamas -- (productosRamas a) es la lista de los productos de las ramas -- del árbol a. Por ejemplo, -- λ> productosRamas (N 3 [N 5 [N 6 []], N 4 [], N 7 [N 2 [], N 1 []]]) -- [90,12,42,21] productosRamas :: (Ord a, Num a) => Arbol a -> [a] productosRamas (N x []) = [x] productosRamas (N x xs) = [x * y | a <- xs, y <- productosRamas a] -- 5ª solución -- =========== mayorProducto5 :: (Ord a, Num a) => Arbol a -> a mayorProducto5 (N x []) = x mayorProducto5 (N x xs) | x > 0 = x * maximum (map mayorProducto5 xs) | x == 0 = 0 | otherwise = x * minimum (map menorProducto xs) -- (menorProducto a) es el menor producto de las ramas del árbol -- a. Por ejemplo, -- λ> menorProducto (N 1 [N 2 [], N 3 []]) -- 2 -- λ> menorProducto (N 1 [N 8 [], N 4 [N 3 []]]) -- 8 -- λ> menorProducto (N 1 [N 2 [],N 3 [N 4 []]]) -- 2 -- λ> menorProducto (N 3 [N 5 [N 6 []], N 4 [], N 7 [N 2 [], N 1 []]]) -- 12 menorProducto :: (Ord a, Num a) => Arbol a -> a menorProducto (N x []) = x menorProducto (N x xs) | x > 0 = x * minimum (map menorProducto xs) | x == 0 = 0 | otherwise = x * maximum (map mayorProducto2 xs) -- 6ª solución -- =========== mayorProducto6 :: (Ord a, Num a) => Arbol a -> a mayorProducto6 = maximum . aux where aux (N a []) = [a] aux (N a b) = [v,u] where u = maximum g v = minimum g g = map (*a) (concatMap aux b) -- Comprobación de equivalencia -- ============================ -- (arbolArbitrario n) es un árbol aleatorio de orden n. Por ejemplo, -- > sample (arbolArbitrario 5 :: Gen (Arbol Int)) -- N 0 [N 0 []] -- N (-2) [] -- N 4 [] -- N 2 [N 4 []] -- N 8 [] -- N (-2) [N (-9) [],N 7 []] -- N 11 [] -- N (-11) [N 4 [],N 14 []] -- N 10 [N (-3) [],N 13 []] -- N 12 [N 11 []] -- N 20 [N (-18) [],N (-13) []] arbolArbitrario :: Arbitrary a => Int -> Gen (Arbol a) arbolArbitrario n = do x <- arbitrary ms <- sublistOf [0 .. n `div` 2] as <- mapM arbolArbitrario ms return (N x as) -- Arbol es una subclase de Arbitraria instance Arbitrary a => Arbitrary (Arbol a) where arbitrary = sized arbolArbitrario -- La propiedad es prop_mayorProducto :: Arbol Integer -> Bool prop_mayorProducto a = all (== mayorProducto1 a) [f a | f <- [ mayorProducto2 , mayorProducto3 , mayorProducto4 , mayorProducto5 , mayorProducto6 ]] -- La comprobación es -- λ> quickCheck prop_mayorProducto -- +++ OK, passed 100 tests. -- Comparación de eficiencia -- ========================= -- La comparación es -- λ> ejArbol <- generate (arbolArbitrario 600 :: Gen (Arbol Integer)) -- λ> mayorProducto1 ejArbol -- 2419727651266241493467136000 -- (1.87 secs, 1,082,764,480 bytes) -- λ> mayorProducto2 ejArbol -- 2419727651266241493467136000 -- (1.57 secs, 1,023,144,008 bytes) -- λ> mayorProducto3 ejArbol -- 2419727651266241493467136000 -- (1.55 secs, 1,023,144,248 bytes) -- λ> mayorProducto4 ejArbol -- 2419727651266241493467136000 -- (1.60 secs, 824,473,800 bytes) -- λ> mayorProducto5 ejArbol -- 2419727651266241493467136000 -- (0.83 secs, 732,370,352 bytes) -- λ> mayorProducto6 ejArbol -- 2419727651266241493467136000 -- (0.98 secs, 817,473,344 bytes) -- -- λ> ejArbol2 <- generate (arbolArbitrario 700 :: Gen (Arbol Integer)) -- λ> mayorProducto5 ejArbol2 -- 1044758937398026715504640000000 -- (4.94 secs, 4,170,324,376 bytes) -- λ> mayorProducto6 ejArbol2 -- 1044758937398026715504640000000 -- (5.88 secs, 4,744,782,024 bytes) |
El código se encuentra en GitHub.
La elaboración de las soluciones se describe en el siguiente vídeo
2. Diferencia simétrica
La diferencia simétrica de dos conjuntos es el conjunto cuyos elementos son aquellos que pertenecen a alguno de los conjuntos iniciales, sin pertenecer a ambos a la vez. Por ejemplo, la diferencia simétrica de {2,5,3} y {4,2,3,7} es {5,4,7}.
Definir la función
1 |
diferenciaSimetrica :: Ord a => [a] -> [a] -> [a] |
tal que (diferenciaSimetrica xs ys)
es la diferencia simétrica de xs
e ys
. Por ejemplo,
1 2 3 4 5 |
diferenciaSimetrica [2,5,3] [4,2,3,7] == [4,5,7] diferenciaSimetrica [2,5,3] [5,2,3] == [] diferenciaSimetrica [2,5,2] [4,2,3,7] == [3,4,5,7] diferenciaSimetrica [2,5,2] [4,2,4,7] == [4,5,7] diferenciaSimetrica [2,5,2,4] [4,2,4,7] == [5,7] |
Soluciones
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
import Test.QuickCheck import Data.List ((\\), intersect, nub, sort, union) import qualified Data.Set as S -- 1ª solución -- =========== diferenciaSimetrica1 :: Ord a => [a] -> [a] -> [a] diferenciaSimetrica1 xs ys = sort (nub ([x | x <- xs, x `notElem` ys] ++ [y | y <- ys, y `notElem` xs])) -- 2ª solución -- =========== diferenciaSimetrica2 :: Ord a => [a] -> [a] -> [a] diferenciaSimetrica2 xs ys = sort (nub (filter (`notElem` ys) xs ++ filter (`notElem` xs) ys)) -- 3ª solución -- =========== diferenciaSimetrica3 :: Ord a => [a] -> [a] -> [a] diferenciaSimetrica3 xs ys = sort (nub (union xs ys \\ intersect xs ys)) -- 4ª solución -- =========== diferenciaSimetrica4 :: Ord a => [a] -> [a] -> [a] diferenciaSimetrica4 xs ys = [x | x <- sort (nub (xs ++ ys)) , x `notElem` xs || x `notElem` ys] -- 5ª solución -- =========== diferenciaSimetrica5 :: Ord a => [a] -> [a] -> [a] diferenciaSimetrica5 xs ys = S.elems ((xs' `S.union` ys') `S.difference` (xs' `S.intersection` ys')) where xs' = S.fromList xs ys' = S.fromList ys -- Comprobación de equivalencia -- ============================ -- La propiedad es prop_diferenciaSimetrica :: [Int] -> [Int] -> Bool prop_diferenciaSimetrica xs ys = all (== diferenciaSimetrica1 xs ys) [diferenciaSimetrica2 xs ys, diferenciaSimetrica3 xs ys, diferenciaSimetrica4 xs ys, diferenciaSimetrica5 xs ys] -- La comprobación es -- λ> quickCheck prop_diferenciaSimetrica -- +++ OK, passed 100 tests. -- Comparación de eficiencia -- ========================= -- La comparación es -- λ> length (diferenciaSimetrica1 [1..2*10^4] [2,4..2*10^4]) -- 10000 -- (2.34 secs, 10,014,360 bytes) -- λ> length (diferenciaSimetrica2 [1..2*10^4] [2,4..2*10^4]) -- 10000 -- (2.41 secs, 8,174,264 bytes) -- λ> length (diferenciaSimetrica3 [1..2*10^4] [2,4..2*10^4]) -- 10000 -- (5.84 secs, 10,232,006,288 bytes) -- λ> length (diferenciaSimetrica4 [1..2*10^4] [2,4..2*10^4]) -- 10000 -- (5.83 secs, 14,814,184 bytes) -- λ> length (diferenciaSimetrica5 [1..2*10^4] [2,4..2*10^4]) -- 10000 -- (0.02 secs, 7,253,496 bytes) |
El código se encuentra en GitHub.
La elaboración de las soluciones se describe en el siguiente vídeo
3. Conjunto de primos relativos
Dos números enteros positivos son primos relativos si no tienen ningún factor primo en común; es decit, si 1 es su único divisor común. Por ejemplo, 6 y 35 son primos entre sí, pero 6 y 27 no lo son porque ambos son divisibles por 3.
Definir la función
1 |
primosRelativos :: [Int] -> Bool |
tal que (primosRelativos xs)
se verifica si los elementos de xs
son primos relativos dos a dos. Por ejemplo,
1 2 3 4 5 6 |
primosRelativos [6,35] == True primosRelativos [6,27] == False primosRelativos [2,3,4] == False primosRelativos [6,35,11] == True primosRelativos [6,35,11,221] == True primosRelativos [6,35,11,231] == False |
Soluciones
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
import Test.QuickCheck import Data.List (delete, intersect) import Data.Numbers.Primes (primeFactors, primes) import qualified Data.Set as S (disjoint, fromList) -- 1ª solución -- =========== primosRelativos1 :: [Int] -> Bool primosRelativos1 [] = True primosRelativos1 (x:xs) = and [sonPrimosRelativos1 x y | y <- xs] && primosRelativos1 xs -- (sonPrimosRelativos x y) se verifica si x e y son primos -- relativos. Por ejemplo, -- sonPrimosRelativos1 6 35 == True -- sonPrimosRelativos1 6 27 == False sonPrimosRelativos1 :: Int -> Int -> Bool sonPrimosRelativos1 x y = null (divisoresPrimos x `intersect` divisoresPrimos y) -- (divisoresPrimos x) es la lista de los divisores primos de x. Por -- ejemplo, -- divisoresPrimos 600 == [2,2,2,3,5,5] divisoresPrimos :: Int -> [Int] divisoresPrimos 1 = [] divisoresPrimos x = y : divisoresPrimos (x `div` y) where y = menorDivisorPrimo x -- (menorDivisorPrimo x) es el menor divisor primo de x. Por ejemplo, -- menorDivisorPrimo 15 == 3 -- menorDivisorPrimo 11 == 11 menorDivisorPrimo :: Int -> Int menorDivisorPrimo x = head [y | y <- [2..], x `mod` y == 0] -- 2ª solución -- =========== primosRelativos2 :: [Int] -> Bool primosRelativos2 [] = True primosRelativos2 (x:xs) = all (sonPrimosRelativos1 x) xs && primosRelativos2 xs -- 3ª solución -- =========== primosRelativos3 :: [Int] -> Bool primosRelativos3 [] = True primosRelativos3 (x:xs) = all (sonPrimosRelativos2 x) xs && primosRelativos3 xs sonPrimosRelativos2 :: Int -> Int -> Bool sonPrimosRelativos2 x y = null (primeFactors x `intersect` primeFactors y) -- 4ª solución -- =========== primosRelativos4 :: [Int] -> Bool primosRelativos4 [] = True primosRelativos4 (x:xs) = all (sonPrimosRelativos3 x) xs && primosRelativos4 xs sonPrimosRelativos3 :: Int -> Int -> Bool sonPrimosRelativos3 x y = S.fromList (primeFactors x) `S.disjoint` S.fromList (primeFactors y) -- 5ª solución -- =========== primosRelativos5 :: [Int] -> Bool primosRelativos5 [] = True primosRelativos5 (x:xs) = all (sonPrimosRelativos5 x) xs && primosRelativos5 xs sonPrimosRelativos5 :: Int -> Int -> Bool sonPrimosRelativos5 x y = gcd x y == 1 -- Comprobación de equivalencia -- ============================ -- La propiedad es prop_primosRelativos :: [Positive Int] -> Bool prop_primosRelativos xs = all (== primosRelativos1 ys) [primosRelativos2 ys, primosRelativos3 ys, primosRelativos4 ys, primosRelativos5 ys] where ys = getPositive <$> xs -- La comprobación es -- λ> quickCheck prop_primosRelativos -- +++ OK, passed 100 tests. -- Comparación de eficiencia -- ========================= -- La comparación es -- λ> primosRelativos1 (take 120 primes) -- True -- (1.92 secs, 869,909,416 bytes) -- λ> primosRelativos2 (take 120 primes) -- True -- (1.99 secs, 869,045,656 bytes) -- λ> primosRelativos3 (take 120 primes) -- True -- (0.09 secs, 221,183,200 bytes) -- -- λ> primosRelativos3 (take 600 primes) -- True -- (2.62 secs, 11,196,690,856 bytes) -- λ> primosRelativos4 (take 600 primes) -- True -- (2.66 secs, 11,190,940,456 bytes) -- λ> primosRelativos5 (take 600 primes) -- True -- (0.14 secs, 123,673,648 bytes) |
El código se encuentra en GitHub.
La elaboración de las soluciones se describe en el siguiente vídeo
4. Familias de números con algún dígito en común
Una familia de números es una lista de números tal que todos tienen la misma cantidad de dígitos y, además, dichos números tienen al menos un dígito común.
Por ejemplo, los números 72, 32, 25 y 22 pertenecen a la misma familia ya que son números de dos dígitos y todos tienen el dígito 2, mientras que los números 123, 245 y 568 no pertenecen a la misma familia, ya que no hay un dígito que aparezca en los tres números.
Definir la función
1 |
esFamilia :: [Integer] -> Bool |
tal que (esFamilia ns)
se verifica si ns
es una familia de números. Por ejemplo,
1 2 3 4 5 |
esFamilia [72, 32, 25, 22] == True esFamilia [123,245,568] == False esFamilia [72, 32, 25, 223] == False esFamilia [56] == True esFamilia [] == True |
Soluciones
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
import Data.List (intersect, nub) import Test.QuickCheck (quickCheck) -- 1ª solución -- =========== esFamilia1 :: [Integer] -> Bool esFamilia1 [] = True esFamilia1 ns = igualNumeroElementos dss && tieneElementoComun dss where dss = map show ns -- (igualNumeroElementos xss) se verifica si todas las listas de xss -- tienen el mismo número de elementos. Por ejemplo, -- igualNumeroElementos [[1,3],[2,2],[4,9]] == True -- igualNumeroElementos [[1,3],[2,1,2],[4,9]] == False igualNumeroElementos :: [[a]] -> Bool igualNumeroElementos xss = iguales (map length xss) -- (iguales xs) se verifica si todos los elementos de xs son -- iguales. Por ejemplo, -- iguales [3,3,3,3] == True -- iguales [3,3,7,3] == False iguales :: Eq a => [a] -> Bool iguales [] = True iguales (x:xs) = all (==x) xs -- (tieneElementoComun xss) se verifican si todas las listas de xss -- tienen algún elemento común. Por ejemplo, -- tieneElementoComun [[1,2],[2,3],[4,2,7]] == True -- tieneElementoComun [[1,2],[2,3],[4,3,7]] == False tieneElementoComun :: Eq a => [[a]] -> Bool tieneElementoComun [] = False tieneElementoComun (xs:xss) = any (`esElementoComun` xss) xs -- (esElementoComun x yss) se verifica si x pertenece a todos los -- elementos de yss. Por ejemplo, -- esElementoComun 2 [[1,2],[2,3],[4,2,7]] == True -- esElementoComun 2 [[1,2],[2,3],[4,3,7]] == False esElementoComun :: Eq a => a -> [[a]] -> Bool esElementoComun x = all (x `elem`) -- 2ª solución -- =========== esFamilia2 :: [Integer] -> Bool esFamilia2 [] = True esFamilia2 ns = igualNumeroElementos2 dss && tieneElementoComun2 dss where dss = map show ns igualNumeroElementos2 :: [[a]] -> Bool igualNumeroElementos2 xss = length (nub (map length xss)) == 1 tieneElementoComun2 :: Eq a => [[a]] -> Bool tieneElementoComun2 xss = not (null (foldl1 intersect xss)) -- 3ª solución -- =========== esFamilia3 :: [Integer] -> Bool esFamilia3 [] = True esFamilia3 ns = igualNumeroElementos3 dss && tieneElementoComun3 dss where dss = map show ns igualNumeroElementos3 :: [[a]] -> Bool igualNumeroElementos3 = ((==1) . length) . nub . map length tieneElementoComun3 :: Eq a => [[a]] -> Bool tieneElementoComun3 = (not . null) . foldl1 intersect -- Comprobación de equivalencia -- ============================ -- La propiedad es prop_esFamilia :: [Integer] -> Bool prop_esFamilia xss = all (== esFamilia1 xss) [esFamilia2 xss, esFamilia3 xss] -- La comprobación es -- λ> quickCheck prop_esFamilia -- +++ OK, passed 100 tests. -- Comparación de eficiencia -- ========================= -- La comparación es -- λ> esFamilia1 [10^6..4*10^6] -- False -- (1.85 secs, 1,931,162,984 bytes) -- λ> esFamilia2 [10^6..4*10^6] -- False -- (2.31 secs, 2,288,177,752 bytes) -- λ> esFamilia3 [10^6..4*10^6] -- False -- (2.23 secs, 2,288,177,864 bytes) |
El código se encuentra en GitHub.
La elaboración de las soluciones se describe en el siguiente vídeo
5. Biparticiones de una lista
Definir la función
1 |
biparticiones :: [a] -> [([a],[a])] |
tal que (biparticiones xs)
es la lista de pares formados por un prefijo de xs
y el resto de xs
. Por ejemplo,
1 2 3 4 |
λ> biparticiones [3,2,5] [([],[3,2,5]),([3],[2,5]),([3,2],[5]),([3,2,5],[])] λ> biparticiones "Roma" [("","Roma"),("R","oma"),("Ro","ma"),("Rom","a"),("Roma","")] |
Soluciones
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
import Data.List (inits, tails) import Control.Applicative (liftA2) import Test.QuickCheck (quickCheck) -- 1ª solución -- =========== biparticiones1 :: [a] -> [([a],[a])] biparticiones1 [] = [([],[])] biparticiones1 (x:xs) = ([],(x:xs)) : [(x:ys,zs) | (ys,zs) <- biparticiones1 xs] -- 2ª solución -- =========== biparticiones2 :: [a] -> [([a],[a])] biparticiones2 xs = [(take i xs, drop i xs) | i <- [0..length xs]] -- 3ª solución -- =========== biparticiones3 :: [a] -> [([a],[a])] biparticiones3 xs = [splitAt i xs | i <- [0..length xs]] -- 4ª solución -- =========== biparticiones4 :: [a] -> [([a],[a])] biparticiones4 xs = zip (inits xs) (tails xs) -- 5ª solución -- =========== biparticiones5 :: [a] -> [([a],[a])] biparticiones5 = liftA2 zip inits tails -- 6ª solución -- =========== biparticiones6 :: [a] -> [([a],[a])] biparticiones6 = zip <$> inits <*> tails -- Comprobación de equivalencia -- ============================ -- La propiedad es prop_biparticiones :: [Int] -> Bool prop_biparticiones xs = all (== biparticiones1 xs) [biparticiones2 xs, biparticiones3 xs, biparticiones4 xs, biparticiones5 xs, biparticiones6 xs] -- La comprobación es -- λ> quickCheck prop_biparticiones -- +++ OK, passed 100 tests. -- Comparación de eficiencia -- ========================= -- La comparación es -- λ> length (biparticiones1 [1..6*10^3]) -- 6001 -- (2.21 secs, 3,556,073,552 bytes) -- λ> length (biparticiones2 [1..6*10^3]) -- 6001 -- (0.01 secs, 2,508,448 bytes) -- -- λ> length (biparticiones2 [1..6*10^6]) -- 6000001 -- (2.26 secs, 2,016,494,864 bytes) -- λ> length (biparticiones3 [1..6*10^6]) -- 6000001 -- (2.12 secs, 1,584,494,792 bytes) -- λ> length (biparticiones4 [1..6*10^6]) -- 6000001 -- (0.78 secs, 1,968,494,704 bytes) -- λ> length (biparticiones5 [1..6*10^6]) -- 6000001 -- (0.79 secs, 1,968,494,688 bytes) -- λ> length (biparticiones6 [1..6*10^6]) -- 6000001 -- (0.77 secs, 1,968,494,720 bytes) -- -- λ> length (biparticiones4 [1..10^7]) -- 10000001 -- (1.30 secs, 3,280,495,432 bytes) -- λ> length (biparticiones5 [1..10^7]) -- 10000001 -- (1.42 secs, 3,280,495,416 bytes) -- λ> length (biparticiones6 [1..10^7]) -- 10000001 -- (1.30 secs, 3,280,495,448 bytes) |
El código se encuentra en GitHub.
La elaboración de las soluciones se describe en el siguiente vídeo