{"id":6802,"date":"2019-10-23T11:35:54","date_gmt":"2019-10-23T09:35:54","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=6802"},"modified":"2019-10-23T19:59:53","modified_gmt":"2019-10-23T17:59:53","slug":"i1m2019-ejercicios-de-definiciones-por-comprension","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/i1m2019-ejercicios-de-definiciones-por-comprension\/","title":{"rendered":"I1M2019: Ejercicios de definiciones por comprensi\u00f3n"},"content":{"rendered":"<p>En la clase de hoy del curso de <a href=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-19\">Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas<\/a> se han comentado soluciones de los ejercicios de la 3\u00aa relaci\u00f3n sobre definiciones por comprensi\u00f3n.<\/p>\n<p>Los ejercicios y su soluci\u00f3n se muestran a continuaci\u00f3n<br \/>\n<!--more--><\/p>\n<pre lang=\"haskell\">\n-- ---------------------------------------------------------------------\n-- Introducci\u00f3n                                                       --\n-- ---------------------------------------------------------------------\n\n-- En esta relaci\u00f3n se presentan ejercicios con definiciones por\n-- comprensi\u00f3n correspondientes al tema 5 que se encuentra\n--    http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-18temas\/tema-5.html\n\n-- ---------------------------------------------------------------------\n-- \u00a7 Librer\u00edas auxiliares                                             --\n-- ---------------------------------------------------------------------\n\nimport Test.QuickCheck\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 1.1. (Problema 6 del proyecto Euler) En los distintos\n-- apartados de este ejercicio se definen funciones para resolver el\n-- problema 6 del proyecto Euler https:\/\/www.projecteuler.net\/problem=6\n--\n-- Definir la funci\u00f3n \n--    suma :: Integer -> Integer\n-- tal (suma n) es la suma de los n primeros n\u00fameros. Por ejemplo,\n--    suma 3  ==  6\n--    length (show (suma (10^100)))  ==  200\n-- ---------------------------------------------------------------------\n\n-- 1\u00aa definici\u00f3n\nsuma :: Integer -> Integer\nsuma n = sum [1..n]\n\n-- 2\u00aa definici\u00f3n\nsuma2 :: Integer -> Integer\nsuma2 n = (1+n)*n `div` 2\n\n-- Equivalencia:\nprop_suma :: Integer -> Property\nprop_suma n =\n  n >= 0 ==> suma n == suma2 n\n\n-- Comprobaci\u00f3n  \n--    \u03bb> quickCheck prop_suma\n--    +++ OK, passed 100 tests.\n\n-- Comparaci\u00f3n de eficiencia\n--    \u03bb> suma (10^7)\n--    50000005000000\n--    (3.39 secs, 1,612,715,016 bytes)\n--    \u03bb> suma2 (10^7)\n--    50000005000000\n--    (0.01 secs, 414,576 bytes)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 1.2 Definir la funci\u00f3n \n--    sumaDeCuadrados :: Integer -> Integer \n-- tal que (sumaDeCuadrados n) es la suma de los cuadrados de los\n-- primeros n n\u00fameros; es decir, 1^2 + 2^2 + ... + n^2. Por ejemplo,\n--    sumaDeCuadrados 3    ==  14\n--    sumaDeCuadrados 100  ==  338350\n--    length (show (sumaDeCuadrados (10^100)))  ==  300\n-- ---------------------------------------------------------------------\n\n-- 1\u00aa soluci\u00f3n\nsumaDeCuadrados :: Integer -> Integer \nsumaDeCuadrados n = sum [x^2 | x <- [1..n]]\n\n-- 2\u00aa soluci\u00f3n\nsumaDeCuadrados2 :: Integer -> Integer \nsumaDeCuadrados2 n = n*(n+1)*(2*n+1) `div` 6\n\n-- Equivalencia:\nprop_sumaDeCuadrados :: Integer -> Property\nprop_sumaDeCuadrados n =\n  n >= 0 ==> sumaDeCuadrados n == sumaDeCuadrados2 n\n\n-- Comprobaci\u00f3n:\n--    \u03bb> quickCheck prop_sumaDeCuadrados\n--    +++ OK, passed 100 tests.\n\n-- Comparaci\u00f3n de eficiencia:\n--    \u03bb> sumaDeCuadrados (10^7)\n--    333333383333335000000\n--    (14.74 secs, 8,025,345,712 bytes)\n--    \u03bb> sumaDeCuadrados2 (10^7)\n--    333333383333335000000\n--    (0.01 secs, 422,168 bytes)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3.3. Definir la funci\u00f3n \n--    euler6 :: Integer -> Integer\n-- tal que (euler6 n) es la diferencia entre el cuadrado de la suma\n-- de los n primeros n\u00fameros y la suma de los cuadrados de los n\n-- primeros n\u00fameros. Por ejemplo, \n--    euler6 10       ==  2640\n--    euler6 (10^10)  ==  2500000000166666666641666666665000000000\n-- ---------------------------------------------------------------------\n\n-- 1\u00aa soluci\u00f3n\neuler6 :: Integer -> Integer\neuler6 n = (suma n)^2 - sumaDeCuadrados n \n\n-- 2\u00aa soluci\u00f3n\neuler6b :: Integer -> Integer\neuler6b n = (suma2 n)^ 2 - sumaDeCuadrados2 n \n\n-- Comparaci\u00f3n de eficiencia\n--    \u03bb> euler6 (10^7)\n--    2500000166666641666665000000\n--    (17.86 secs, 9,637,652,608 bytes)\n--    \u03bb> euler6b (10^7)\n--    2500000166666641666665000000\n--    (0.01 secs, 426,656 bytes)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 2. Definir por comprensi\u00f3n la funci\u00f3n \n--    replica :: Int -> a -> [a]\n-- tal que (replica n x) es la lista formada por n copias del elemento\n-- x. Por ejemplo,  \n--    replica 4 7     ==  [7,7,7,7]\n--    replica 3 True  ==  [True, True, True]\n-- Nota: La funci\u00f3n replica es equivalente a la predefinida replicate.\n-- ---------------------------------------------------------------------\n\nreplica :: Int -> a -> [a]\nreplica n x = [x | _ <- [1..n]]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3.1. Los tri\u00e1ngulos aritm\u00e9ticos se forman como sigue\n--     1\n--     2  3\n--     4  5  6\n--     7  8  9 10\n--    11 12 13 14 15\n--    16 17 18 19 20 21\n--\n-- Definir la funci\u00f3n\n--    linea :: Integer -> [Integer]\n-- tal que (linea n) es la l\u00ednea n-\u00e9sima de los tri\u00e1ngulos\n-- aritm\u00e9ticos. Por ejemplo,  \n--    linea 4  ==  [7,8,9,10]\n--    linea 5  ==  [11,12,13,14,15]\n--    head (linea (10^20))  ==  4999999999999999999950000000000000000001\n-- ---------------------------------------------------------------------\n\n-- 1\u00aa definici\u00f3n\nlinea1 :: Integer -> [Integer]\nlinea1 n = [suma (n-1)+1..suma n]\n\n-- 2\u00aa definici\u00f3n\nlinea2 :: Integer -> [Integer]\nlinea2 n = [s+1..s+n]\n  where s = suma (n-1)\n\n-- 3\u00aa definici\u00f3n\nlinea3 :: Integer -> [Integer]\nlinea3 n = [s+1..s+n]\n  where s = suma2 (n-1)\n\n-- Equivalencia:\nprop_linea :: Integer -> Property\nprop_linea n =\n  n >= 0\n  ==>\n     linea1 n == linea2 n\n  && linea1 n == linea2 n\n\n-- Comprobaci\u00f3n:\n--    \u03bb> quickCheck prop_linea\n--    +++ OK, passed 100 tests.\n\n-- Comparaci\u00f3n de eficiencia\n--    \u03bb> head (linea1 (3*10^6))\n--    4499998500001\n--    (2.14 secs, 967,773,888 bytes)\n--    \u03bb> head (linea2 (3*10^6))\n--    4499998500001\n--    (0.79 secs, 484,092,656 bytes)\n--    \u03bb> head (linea3 (3*10^6))\n--    4499998500001\n--    (0.01 secs, 414,824 bytes)\n\n-- En lo que sigue, usaremos la 3\u00aa definici\u00f3n\nlinea :: Integer -> [Integer]\nlinea = linea3\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3.2. Definir la funci\u00f3n \n--    triangulo :: Integer -> [[Integer]]\n-- tal que (triangulo n) es el tri\u00e1ngulo aritm\u00e9tico de altura n. Por\n-- ejemplo, \n--    triangulo 3  ==  [[1],[2,3],[4,5,6]]\n--    triangulo 4  ==  [[1],[2,3],[4,5,6],[7,8,9,10]]\n-- ---------------------------------------------------------------------\n\ntriangulo :: Integer -> [[Integer]]\ntriangulo n = [linea m | m <- [1..n]]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 4. Un entero positivo es perfecto si es igual a la suma de\n-- sus factores, excluyendo el propio n\u00famero. \n-- \n-- Definir por comprensi\u00f3n la funci\u00f3n \n--    perfectos :: Int -> [Int]\n-- tal que (perfectos n) es la lista de todos los n\u00fameros perfectos\n-- menores que n. Por ejemplo,  \n--    perfectos 500  ==  [6,28,496]\n-- Indicaci\u00f3n: Usar la funci\u00f3n factores del tema 5.\n-- ---------------------------------------------------------------------\n\nperfectos :: Int -> [Int]\nperfectos n = [x | x <- [1..n], sum (init (factores x)) == x]\n\n-- La funci\u00f3n factores del tema es\nfactores :: Int -> [Int]\nfactores n = [x | x <- [1..n], n `mod` x == 0]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 5.1. Un n\u00famero natural n se denomina abundante si es menor\n-- que la suma de sus divisores propios. Por ejemplo, 12 y 30 son\n-- abundantes pero 5 y 28 no lo son.\n-- \n-- Definir la funci\u00f3n \n--    numeroAbundante :: Int -> Bool\n-- tal que (numeroAbundante n) se verifica si n es un n\u00famero\n-- abundante. Por ejemplo,  \n--    numeroAbundante 5  == False\n--    numeroAbundante 12 == True\n--    numeroAbundante 28 == False\n--    numeroAbundante 30 == True\n-- ---------------------------------------------------------------------\n\nnumeroAbundante :: Int -> Bool\nnumeroAbundante n = n < sum (divisores n)\n\ndivisores :: Int -> [Int]\ndivisores n = [m | m <- [1..n-1], n `mod` m == 0]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 5.2. Definir la funci\u00f3n  \n--    numerosAbundantesMenores :: Int -> [Int]\n-- tal que (numerosAbundantesMenores n) es la lista de n\u00fameros\n-- abundantes menores o iguales que n. Por ejemplo,\n--    numerosAbundantesMenores 50  ==  [12,18,20,24,30,36,40,42,48]\n--    numerosAbundantesMenores 48  ==  [12,18,20,24,30,36,40,42,48]\n-- ---------------------------------------------------------------------\n\nnumerosAbundantesMenores :: Int -> [Int]\nnumerosAbundantesMenores n = [x | x <- [1..n], numeroAbundante x]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 5.3. Definir la funci\u00f3n \n--    todosPares :: Int -> Bool\n-- tal que (todosPares n) se verifica si todos los n\u00fameros abundantes\n-- menores o iguales que n son pares. Por ejemplo,\n--    todosPares 10    ==  True\n--    todosPares 100   ==  True\n--    todosPares 1000  ==  False\n-- ---------------------------------------------------------------------\n\ntodosPares :: Int -> Bool\ntodosPares n = and [even x | x <- numerosAbundantesMenores n]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 5.4. Definir la constante \n--    primerAbundanteImpar :: Int\n-- que calcule el primer n\u00famero natural abundante impar. Determinar el\n-- valor de dicho n\u00famero.\n-- ---------------------------------------------------------------------\n\nprimerAbundanteImpar :: Int\nprimerAbundanteImpar = head [x | x <- [1,3..], numeroAbundante x]\n\n-- Su c\u00e1lculo es\n--    ghci> primerAbundanteImpar\n--    945\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 6 (Problema 1 del proyecto Euler) Definir la funci\u00f3n \n--    euler1 :: Int -> Int\n-- tal que (euler1 n) es la suma de todos los m\u00faltiplos de 3 \u00f3 5 menores\n-- que n. Por ejemplo,\n--    euler1 10  ==  23\n-- \n-- Calcular la suma de todos los m\u00faltiplos de 3 \u00f3 5 menores que 1000.\n-- ---------------------------------------------------------------------\n\neuler1 :: Int -> Int\neuler1 n = sum [x | x <- [1..n-1], multiplo x 3 || multiplo x 5]\n  where multiplo x y = mod x y == 0\n\n-- C\u00e1lculo:\n--    ghci> euler1 1000\n--    233168\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 7. Definir la funci\u00f3n \n--    circulo :: Int -> Int\n-- tal que (circulo n) es el la cantidad de pares de n\u00fameros naturales\n-- (x,y) que se encuentran dentro del c\u00edrculo de radio n. Por ejemplo, \n--    circulo 3  ==  9\n--    circulo 4  ==  15\n--    circulo 5  ==  22\n--    circulo 100  ==  7949\n-- ---------------------------------------------------------------------\n\ncirculo :: Int -> Int\ncirculo n = length [(x,y) | x <- [0..n], y <- [0..n], x*x+y*y < n*n]\n\n-- La eficiencia puede mejorarse con\ncirculo2 :: Int -> Int\ncirculo2 n = length [(x,y) | x <- [0..n-1]\n                           , y <- [0..raizCuadradaEntera (n*n - x*x)]\n                           , x*x+y*y < n*n]\n\n-- (raizCuadradaEntera n) es la parte entera de la ra\u00edz cuadrada de\n-- n. Por ejemplo,\n--    raizCuadradaEntera 17  ==  4 \nraizCuadradaEntera :: Int -> Int\nraizCuadradaEntera n = truncate (sqrt (fromIntegral n))\n\n-- Comparaci\u00f3n de eficiencia\n--    \u03bb> circulo (10^4)\n--    78549754\n--    (73.44 secs, 44,350,688,480 bytes)\n--    \u03bb> circulo2 (10^4)\n--    78549754\n--    (59.71 secs, 36,457,043,240 bytes)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 8.1. Definir la funci\u00f3n \n--    aproxE :: Double -> [Double]\n-- tal que (aproXE n) es la lista cuyos elementos son los t\u00e9rminos de la\n-- sucesi\u00f3n (1+1\/m)**m desde 1 hasta n. Por ejemplo, \n--    aproxE 1 == [2.0]\n--    aproxE 4 == [2.0,2.25,2.37037037037037,2.44140625]\n-- ---------------------------------------------------------------------\n\naproxE :: Double -> [Double]\naproxE n = [(1+1\/m)**m | m <- [1..n]]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 8.2. \u00bfCu\u00e1l es el l\u00edmite de la sucesi\u00f3n (1+1\/m)**m ?\n-- ---------------------------------------------------------------------\n\n-- El l\u00edmite de la sucesi\u00f3n es el n\u00famero e. \n\n-- ---------------------------------------------------------------------\n-- Ejercicio 8.3. Definir la funci\u00f3n \n--    errorAproxE :: Double -> Double\n-- tal que (errorE x) es el menor n\u00famero de t\u00e9rminos de la sucesi\u00f3n\n-- (1+1\/m)**m necesarios para obtener su l\u00edmite con un error menor que\n-- x. Por ejemplo, \n--    errorAproxE 0.1    ==  13.0\n--    errorAproxE 0.01   ==  135.0\n--    errorAproxE 0.001  ==  1359.0\n-- Indicaci\u00f3n: En Haskell, e se calcula como (exp 1).\n-- ---------------------------------------------------------------------\n\nerrorAproxE :: Double -> Double\nerrorAproxE x = head [m | m <- [1..], abs (exp 1 - (1+1\/m)**m) < x]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 9.1. Definir la funci\u00f3n\n--    aproxLimSeno :: Double -> [Double]\n-- tal que (aproxLimSeno n) es la lista cuyos elementos son los t\u00e9rminos\n-- de la sucesi\u00f3n  \n--    sen(1\/m) \n--    --------\n--      1\/m \n-- desde 1 hasta n. Por ejemplo,\n--    aproxLimSeno 1 == [0.8414709848078965]\n--    aproxLimSeno 2 == [0.8414709848078965,0.958851077208406]\n-- ---------------------------------------------------------------------\n\naproxLimSeno :: Double -> [Double]\naproxLimSeno n = [sin(1\/m)\/(1\/m) | m <- [1..n]] \n\n-- ---------------------------------------------------------------------\n-- Ejercicio 9.2. \u00bfCu\u00e1l es el l\u00edmite de la sucesi\u00f3n sen(1\/m)\/(1\/m) ?\n-- ---------------------------------------------------------------------\n\n-- El l\u00edmite es 1.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 9.3. Definir la funci\u00f3n \n--    errorLimSeno :: Double -> Double\n-- tal que (errorLimSeno x) es el menor n\u00famero de t\u00e9rminos de la sucesi\u00f3n \n-- sen(1\/m)\/(1\/m) necesarios para obtener su l\u00edmite con un error menor\n-- que x. Por ejemplo, \n--    errorLimSeno 0.1     ==   2.0\n--    errorLimSeno 0.01    ==   5.0\n--    errorLimSeno 0.001   ==  13.0\n--    errorLimSeno 0.0001  ==  41.0\n-- ---------------------------------------------------------------------\n\nerrorLimSeno :: Double -> Double\nerrorLimSeno x = head [m | m <- [1..], abs (1 - sin(1\/m)\/(1\/m)) < x]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 10.1. Definir la funci\u00f3n \n--    calculaPi :: Double -> Double\n-- tal que (calculaPi n) es la aproximaci\u00f3n del n\u00famero pi calculada\n-- mediante la expresi\u00f3n \n--    4*(1 - 1\/3 + 1\/5 - 1\/7 + ...+ (-1)**n\/(2*n+1))\n-- Por ejemplo,\n--    calculaPi 3    ==  2.8952380952380956\n--    calculaPi 300  ==  3.1449149035588526\n-- ---------------------------------------------------------------------\n\ncalculaPi :: Double -> Double\ncalculaPi n = 4 * sum [(-1)**x\/(2*x+1) | x <- [0..n]]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 10.2. Definir la funci\u00f3n \n--    errorPi :: Double -> Double\n-- tal que (errorPi x) es el menor n\u00famero de t\u00e9rminos de la serie\n--    4*(1 - 1\/3 + 1\/5 - 1\/7 + ...+ (-1)**n\/(2*n+1))\n-- necesarios para obtener pi con un error menor que x. Por ejemplo,\n--    errorPi 0.1    ==    9.0\n--    errorPi 0.01   ==   99.0\n--    errorPi 0.001  ==  999.0\n-- ---------------------------------------------------------------------\n\nerrorPi :: Double -> Double\nerrorPi x = head [n | n <- [1..]\n                    , abs (pi - calculaPi n) < x]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 11.1. Una terna (x,y,z) de enteros positivos es pitag\u00f3rica\n-- si x^2 + y^2 = z^2. \n-- \n-- Definir, por comprensi\u00f3n, la funci\u00f3n \n--    pitagoricas :: Int -> [(Int,Int,Int)]\n-- tal que (pitagoricas n) es la lista de todas las ternas pitag\u00f3ricas\n-- cuyas componentes est\u00e1n entre 1 y n. Por ejemplo, \n--    pitagoricas 10  ==  [(3,4,5),(4,3,5),(6,8,10),(8,6,10)]\n-- ---------------------------------------------------------------------\n\npitagoricas :: Int -> [(Int,Int,Int)]\npitagoricas n = [(x,y,z) | x <- [1..n]\n                         , y <- [1..n]\n                         , z <- [1..n]\n                         , x^2 + y^2 == z^2]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 11.2. Definir la funci\u00f3n \n--    numeroDePares :: (Int,Int,Int) -> Int\n-- tal que (numeroDePares t) es el n\u00famero de elementos pares de la terna\n-- t. Por ejemplo,\n--    numeroDePares (3,5,7)  ==  0\n--    numeroDePares (3,6,7)  ==  1\n--    numeroDePares (3,6,4)  ==  2\n--    numeroDePares (4,6,4)  ==  3\n-- ---------------------------------------------------------------------\n\nnumeroDePares :: (Int,Int,Int) -> Int\nnumeroDePares (x,y,z) = length [1 | n <- [x,y,z], even n]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 11.3. Definir la funci\u00f3n\n--    conjetura :: Int -> Bool\n-- tal que (conjetura n) se verifica si todas las ternas pitag\u00f3ricas\n-- cuyas componentes est\u00e1n entre 1 y n tiene un n\u00famero impar de n\u00fameros\n-- pares. Por ejemplo,\n--    conjetura 10  ==  True\n-- ---------------------------------------------------------------------\n\nconjetura :: Int -> Bool\nconjetura n = and [odd (numeroDePares t) | t <- pitagoricas n]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 11.4. Demostrar la conjetura para todas las ternas\n-- pitag\u00f3ricas. \n-- ---------------------------------------------------------------------\n\n-- Sea (x,y,z) una terna pitag\u00f3rica. Entonces x^2+y^2=z^2. Pueden darse\n-- 4 casos:\n-- \n-- Caso 1: x e y son pares. Entonces, x^2, y^2 y z^2 tambi\u00e9n lo\n-- son. Luego el n\u00famero de componentes pares es 3 que es impar.\n-- \n-- Caso 2: x es par e y es impar. Entonces, x^2 es par, y^2 es impar y\n-- z^2 es impar. Luego el n\u00famero de componentes pares es 1 que es impar.\n-- \n-- Caso 3: x es impar e y es par. An\u00e1logo al caso 2.\n-- \n-- Caso 4: x e y son impares. Entonces, x^2 e y^2 tambi\u00e9n son impares y\n-- z^2 es par. Luego el n\u00famero de componentes pares es 1 que es impar.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 12.1. (Problema 9 del proyecto Euler). Una terna pitag\u00f3rica\n-- es una terna de n\u00fameros naturales (a,b,c) tal que a<b<c y\n-- a^2+b^2=c^2. Por ejemplo (3,4,5) es una terna pitag\u00f3rica. \n-- \n-- Definir la funci\u00f3n \n--    ternasPitagoricas :: Integer -> [[Integer]]\n-- tal que (ternasPitagoricas x) es la lista de las ternas pitag\u00f3ricas\n-- cuya suma es x. Por ejemplo,\n--    ternasPitagoricas 12  ==  [(3,4,5)]\n--    ternasPitagoricas 60  ==  [(10,24,26),(15,20,25)]\n-- ---------------------------------------------------------------------\n\nternasPitagoricas :: Integer -> [(Integer,Integer,Integer)]\nternasPitagoricas x = [(a,b,c) | a <- [1..x], \n                                 b <- [a+1..x], \n                                 c <- [x-a-b],\n                                 b < c,\n                                 a^2 + b^2 == c^2]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 12.2. Definir la constante \n--    euler9 :: Integer\n-- tal que euler9 es producto abc donde (a,b,c) es la \u00fanica terna\n-- pitag\u00f3rica tal que a+b+c=1000.  \n--\n-- Calcular el valor de euler9.\n-- ---------------------------------------------------------------------\n\neuler9 :: Integer\neuler9 = a*b*c\n    where (a,b,c) = head (ternasPitagoricas 1000)\n\n-- El c\u00e1lculo del valor de euler9 es\n--    ghci> euler9\n--    31875000\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 13. El producto escalar de dos listas de enteros xs y ys de\n-- longitud n viene dado por la suma de los productos de los elementos\n-- correspondientes. \n-- \n-- Definir por comprensi\u00f3n la funci\u00f3n \n--    productoEscalar :: [Int] -> [Int] -> Int\n-- tal que (productoEscalar xs ys) es el producto escalar de las listas\n-- xs e ys. Por ejemplo,\n--    productoEscalar [1,2,3] [4,5,6]  ==  32\n-- ---------------------------------------------------------------------\n\nproductoEscalar :: [Int] -> [Int] -> Int\nproductoEscalar xs ys = sum [x*y | (x,y) <- zip xs ys]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 14. Definir, por comprensi\u00f3n, la funci\u00f3n\n--    sumaConsecutivos :: [Int] -> [Int]\n-- tal que (sumaConsecutivos xs) es la suma de los pares de elementos\n-- consecutivos de la lista xs. Por ejemplo,\n--    sumaConsecutivos [3,1,5,2]  ==  [4,6,7]\n--    sumaConsecutivos [3]        ==  []\n-- ---------------------------------------------------------------------\n\nsumaConsecutivos :: [Int] -> [Int]\nsumaConsecutivos xs = [x+y | (x,y) <- zip xs (tail xs)]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 15. Los polinomios pueden representarse de forma dispersa o\n-- densa. Por ejemplo, el polinomio 6x^4-5x^2+4x-7 se puede representar\n-- de forma dispersa por [6,0,-5,4,-7] y de forma densa por\n-- [(4,6),(2,-5),(1,4),(0,-7)].  \n-- \n-- Definir la funci\u00f3n \n--    densa :: [Int] -> [(Int,Int)]\n-- tal que (densa xs) es la representaci\u00f3n densa del polinomio cuya\n-- representaci\u00f3n dispersa es xs. Por ejemplo, \n--   densa [6,0,-5,4,-7]  ==  [(4,6),(2,-5),(1,4),(0,-7)]\n--   densa [6,0,0,3,0,4]  ==  [(5,6),(2,3),(0,4)]\n-- ---------------------------------------------------------------------\n\ndensa :: [Int] -> [(Int,Int)]\ndensa xs = [(x,y) | (x,y) <- zip [n-1,n-2..0] xs, y \/= 0]\n  where n = length xs\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 16. La bases de datos sobre actividades de personas pueden\n-- representarse mediante listas de elementos de la forma (a,b,c,d),\n-- donde a es el nombre de la persona, b su actividad, c su fecha de\n-- nacimiento y d la de su fallecimiento. Un ejemplo es la siguiente que\n-- usaremos a lo largo de este ejercicio,\n-- ---------------------------------------------------------------------\n\npersonas :: [(String,String,Int,Int)]\npersonas = [(\"Cervantes\",\"Literatura\",1547,1616),\n            (\"Velazquez\",\"Pintura\",1599,1660),\n            (\"Picasso\",\"Pintura\",1881,1973),\n            (\"Beethoven\",\"Musica\",1770,1823),\n            (\"Poincare\",\"Ciencia\",1854,1912),\n            (\"Quevedo\",\"Literatura\",1580,1654),\n            (\"Goya\",\"Pintura\",1746,1828),\n            (\"Einstein\",\"Ciencia\",1879,1955),\n            (\"Mozart\",\"Musica\",1756,1791),\n            (\"Botticelli\",\"Pintura\",1445,1510),\n            (\"Borromini\",\"Arquitectura\",1599,1667),\n            (\"Bach\",\"Musica\",1685,1750)]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 16.1. Definir la funci\u00f3n\n--    nombres :: [(String,String,Int,Int)] -> [String]\n-- tal que (nombres bd) es la lista de los nombres de las personas de la\n-- base de datos bd. Por ejemplo,  \n--    ghci> nombres personas\n--     [\"Cervantes\",\"Velazquez\",\"Picasso\",\"Beethoven\",\"Poincare\",\n--      \"Quevedo\",\"Goya\",\"Einstein\",\"Mozart\",\"Botticelli\",\"Borromini\",\"Bach\"]\n-- ---------------------------------------------------------------------\n\nnombres :: [(String,String,Int,Int)] -> [String]\nnombres bd = [x | (x,_,_,_) <- bd]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 16.2. Definir la funci\u00f3n\n--    musicos :: [(String,String,Int,Int)] -> [String]\n-- tal que (musicos bd) es la lista de los nombres de los m\u00fasicos de la\n-- base de datos bd. Por ejemplo,  \n--    musicos personas  ==  [\"Beethoven\",\"Mozart\",\"Bach\"]\n-- ---------------------------------------------------------------------\n\nmusicos :: [(String,String,Int,Int)] -> [String]\nmusicos bd = [x | (x,\"Musica\",_,_) <- bd]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 16.3. Definir la funci\u00f3n \n--    seleccion :: [(String,String,Int,Int)] -> String -> [String]\n-- tal que (seleccion bd m) es la lista de los nombres de las personas\n-- de la base de datos bd cuya actividad es m. Por ejemplo,  \n--    ghci> seleccion personas \"Pintura\"\n--    [\"Velazquez\",\"Picasso\",\"Goya\",\"Botticelli\"]\n--    ghci> seleccion personas \"Musica\"\n--    [\"Beethoven\",\"Mozart\",\"Bach\"]\n-- ---------------------------------------------------------------------\n\nseleccion :: [(String,String,Int,Int)] -> String -> [String]\nseleccion bd m = [ x | (x,m',_,_) <- bd, m == m' ]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 16.4. Definir, usando el apartado anterior, la funci\u00f3n\n--    musicos' :: [(String,String,Int,Int)] -> [String]\n-- tal que (musicos' bd) es la lista de los nombres de los m\u00fasicos de la\n-- base de datos bd. Por ejemplo,   \n--    ghci> musicos' personas\n--    [\"Beethoven\",\"Mozart\",\"Bach\"]\n-- ---------------------------------------------------------------------\n\nmusicos' :: [(String,String,Int,Int)] -> [String]\nmusicos' bd = seleccion bd \"Musica\"\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 16.5. Definir la funci\u00f3n \n--    vivas :: [(String,String,Int,Int)] -> Int -> [String]\n-- tal que (vivas bd a) es la lista de los nombres de las personas de la\n-- base de datos bd  que estaban vivas en el a\u00f1o a. Por ejemplo,  \n--    ghci> vivas personas 1600\n--    [\"Cervantes\",\"Velazquez\",\"Quevedo\",\"Borromini\"]\n-- ---------------------------------------------------------------------\n\nvivas :: [(String,String,Int,Int)] -> Int -> [String]\nvivas ps a = [x | (x,_,a1,a2) <- ps, a1 <= a, a <= a2]\n<\/pre>\n<p>En la tercera parte se ha realizado un ejercicio de autoevaluaci\u00f3n en el laboratorio.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>En la clase de hoy del curso de Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas se han comentado soluciones de los ejercicios de la 3\u00aa relaci\u00f3n sobre definiciones por comprensi\u00f3n. Los ejercicios y su soluci\u00f3n se muestran a continuaci\u00f3n<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"footnotes":"","_jetpack_memberships_contains_paid_content":false},"categories":[331],"tags":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":false,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/6802"}],"collection":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/comments?post=6802"}],"version-history":[{"count":3,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/6802\/revisions"}],"predecessor-version":[{"id":6806,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/6802\/revisions\/6806"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=6802"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=6802"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=6802"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}