Productos de sumas de cuatro cuadrados
Definir la función
1 |
productoSuma4Cuadrados :: Integral a => [a] -> [a] -> [a] -> [a] -> a |
tal que (productoSuma4Cuadrados as bs cs ds) es el producto de las sumas de los cuadrados de cada una de las listas que ocupan la misma posición (hasta que alguna se acaba). Por ejemplo,
1 2 3 4 |
productoSuma4Cuadrados [2,3] [1,5] [4,6] [0,3,9] = (2² + 1² + 4² + 0²) * (3² + 5² + 6² + 3²) = (4 + 1 + 16 + 0) * (9 + 25 + 36 + 9) = 1659 |
Comprobar con QuickCheckWith que si as, bs cs y ds son listas no vacías de enteros positivos, entonces (productoSuma4Cuadrados as bs cs ds) se puede escribir como la suma de los cuadrados de cuatro enteros positivos.
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 |
import Data.List (zip4) import Test.QuickCheck -- 1ª solución -- =========== productoSuma4Cuadrados :: Integral a => [a] -> [a] -> [a] -> [a] -> a productoSuma4Cuadrados (a:as) (b:bs) (c:cs) (d:ds) = (a^2+b^2+c^2+d^2) * productoSuma4Cuadrados as bs cs ds productoSuma4Cuadrados _ _ _ _ = 1 -- 2ª solución -- =========== productoSuma4Cuadrados2 :: Integral a => [a] -> [a] -> [a] -> [a] -> a productoSuma4Cuadrados2 as bs cs ds = product [a^2 + b^2 + c^2 + d^2 | (a,b,c,d) <- zip4 as bs cs ds] -- Propiedad -- ========= -- La propiedad es prop_productoSuma4Cuadrados :: [Integer] -> [Integer] -> [Integer] -> [Integer] -> Property prop_productoSuma4Cuadrados as bs cs ds = all (not . null) [as, bs, cs, ds] ==> esSuma4Cuadrados (productoSuma4Cuadrados as' bs' cs' ds') where as' = [1 + abs a | a <- as] bs' = [1 + abs b | b <- bs] cs' = [1 + abs c | c <- cs] ds' = [1 + abs d | d <- ds] -- (esSuma4Cuadrados n) se verifica si n es la suma de 4 cuadrados. Por -- ejemplo, -- esSuma4Cuadrados 42 == True -- esSuma4Cuadrados 11 == False -- esSuma4Cuadrados 41 == False esSuma4Cuadrados :: Integer -> Bool esSuma4Cuadrados = not . null . sumas4Cuadrados -- (sumas4Cuadrados n) es la lista de las descomposiciones de n como -- sumas de 4 cuadrados. Por ejemplo, -- sumas4Cuadrados 42 == [(16,16,9,1),(25,9,4,4),(36,4,1,1)] sumas4Cuadrados :: Integer -> [(Integer,Integer,Integer,Integer)] sumas4Cuadrados n = [(a^2,b^2,c^2,d) | a <- [1 .. floor (sqrt (fromIntegral n / 4))] , b <- [a .. floor (sqrt (fromIntegral (n-a^2) / 3))] , c <- [b .. floor (sqrt (fromIntegral (n-a^2-b^2) / 2))] , let d = n - a^2 - b^2 - c^2 , c^2 <= d , esCuadrado d] -- (esCuadrado x) se verifica si x es un número al cuadrado. Por -- ejemplo, -- esCuadrado 25 == True -- esCuadrado 26 == False esCuadrado :: Integer -> Bool esCuadrado x = x == y * y where y = raiz x -- (raiz x) es la raíz cuadrada entera de x. Por ejemplo, -- raiz 25 == 5 -- raiz 24 == 4 -- raiz 26 == 5 raiz :: Integer -> Integer raiz x = floor (sqrt (fromIntegral x)) -- La comprobación es -- λ> quickCheckWith (stdArgs {maxSize=5}) prop_productoSuma4Cuadrados -- +++ OK, passed 100 tests. |
Otras soluciones
- Se pueden escribir otras soluciones en los comentarios.
- El código se debe escribir entre una línea con <pre lang=»haskell»> y otra con </pre>
Pensamiento
¿Vivir? Sencillamente:
la sed y el agua cerca …
o el agua lejos, más, la sed y el agua,
un poco de cansancio ¡y a beberla!.Antonio Machado
2 Comentarios