{"id":1721,"date":"2011-11-29T20:10:44","date_gmt":"2011-11-29T20:10:44","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=1721"},"modified":"2013-03-08T05:48:59","modified_gmt":"2013-03-08T05:48:59","slug":"i1m2011-ejercicios-de-definiciones-por-recursion-y-comprension-3","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/i1m2011-ejercicios-de-definiciones-por-recursion-y-comprension-3\/","title":{"rendered":"I1M2011: Ejercicios con definiciones por recursi\u00f3n y comprensi\u00f3n en Haskell (3)"},"content":{"rendered":"<p>La clase de hoy de <a href=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-11\">Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas<\/a> hemos terminado continuado comentando soluciones de ejercicios con definiciones por recursi\u00f3n y comprensi\u00f3n. Concretamente, hemos visto los la <a href=\"https:\/\/www.glc.us.es\/~jalonso\/ejerciciosI1M2011G1\/images\/0\/0a\/Rel_7.hs\">7\u00aa relaci\u00f3n<\/a> (que comenzamos en la <a href\"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/i1m2011-ejercicios-de-definiciones-por-recursion-y-comprension-en-haskell-1\/\">clase del d\u00eda 22<\/a> y continuamos en la <a href=\"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/i1m2011-funciones-de-orden-superior-y-ejercicios-de-recursion-y-comprension-en-haskell\">clase del 25<\/a>) y los de la <a href=\"https:\/\/www.glc.us.es\/~jalonso\/ejerciciosI1M2011G1\/images\/0\/0a\/Rel_8.hs\">8\u00aa relaci\u00f3n<\/a>. <\/p>\n<p>Los ejercicios, y sus soluciones, de la 7\u00aa relaci\u00f3n se muestran a continuaci\u00f3n:<br \/>\n<!--more--><\/p>\n<pre lang=\"haskell\">\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 14.1. Definir la funci\u00f3n\r\n--    factores :: Integer -> Integer\r\n-- tal que (factores n) es la lista de los factores de n. Por ejemplo, \r\n--    factores 60  ==  [1,2,3,4,5,6,10,12,15,20,30,60]\r\n-- ---------------------------------------------------------------------\r\n\r\nfactores :: Integer -> [Integer]\r\nfactores n = [x | x <- [1..n], mod n x == 0]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 14.2. Definir la funci\u00f3n\r\n--    primo :: Integer -> Bool\r\n-- tal que (primo n) se verifica si n es primo. Por ejemplo,\r\n--    primo 7  ==  True\r\n--    primo 9  ==  False\r\n-- ---------------------------------------------------------------------\r\n\r\nprimo :: Integer -> Bool\r\nprimo x = factores x == [1,x]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 14.3. Definir la funci\u00f3n\r\n--    factoresPrimos :: Integer -> [Integer]\r\n-- tal que (factoresPrimos n) es la lista de los factores primos de\r\n-- n. Por ejemplo,  \r\n--    factoresPrimos 60  ==  [2,3,5]\r\n-- ---------------------------------------------------------------------\r\n\r\nfactoresPrimos :: Integer -> [Integer]\r\nfactoresPrimos n = [x | x <- factores n, primo x]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 14.4. Definir la funci\u00f3n\r\n--    factorizacion :: Integer -> [(Integer,Integer)]\r\n-- tal que (factorizacion n) es la factorizaci\u00f3n de n. Por ejemplo,  \r\n--    factorizacion 60  ==  [(2,2),(3,1),(5,1)]\r\n-- ---------------------------------------------------------------------\r\n\r\nfactorizacion :: Integer -> [(Integer,Integer)]\r\nfactorizacion n = [(x,mayorExponenteR x n) | x <- factoresPrimos n]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 14.5. Definir, por recursi\u00f3n, la funci\u00f3n\r\n--    expansionR :: [(Integer,Integer)] -> Integer\r\n-- tal que (expansionR xs) es la expansi\u00f3n de la factorizaci\u00f3n de\r\n-- xs. Por ejemplo,   \r\n--    expansionR [(2,2),(3,1),(5,1)]  ==  60\r\n-- ---------------------------------------------------------------------\r\n\r\nexpansionR :: [(Integer,Integer)] -> Integer\r\nexpansionR [] = 1\r\nexpansionR ((x,y):zs) = x^y * expansionR zs\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 14.6. Definir, por comprensi\u00f3n, la funci\u00f3n\r\n--    expansionC :: [(Integer,Integer)] -> Integer\r\n-- tal que (expansionC xs) es la expansi\u00f3n de la factorizaci\u00f3n de\r\n-- xs. Por ejemplo,   \r\n--    expansionC [(2,2),(3,1),(5,1)]  ==  60\r\n-- ---------------------------------------------------------------------\r\n\r\nexpansionC :: [(Integer,Integer)] -> Integer\r\nexpansionC xs = product [x^y | (x,y) <- xs]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 14.7. Definir la funci\u00f3n\r\n--    prop_factorizacion :: Integer -> Bool\r\n-- tal que (prop_factorizacion n) se verifica si para todo n\u00famero\r\n-- natural x, menor o igual que n, se tiene que \r\n-- (expansionC (factorizacion x)) es igual a x. Por ejemplo,\r\n--    prop_factorizacion 100  ==  True\r\n-- ---------------------------------------------------------------------\r\n\r\nprop_factorizacion n =\r\n    and [expansionC (factorizacion x) == x | x <- [1..n]]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 15. En un templo hind\u00fa se encuentran tres varillas de\r\n-- platino. En una de ellas, hay 64 anillos de oro de distintos radios,\r\n-- colocados de mayor a menor.\r\n-- \r\n-- El trabajo de los monjes de ese templo consiste en pasarlos todos a\r\n-- la tercera varilla, usando la segunda como varilla auxiliar, con las\r\n-- siguientes condiciones: \r\n--   * En cada paso s\u00f3lo se puede mover un anillo.\r\n--   * Nunca puede haber un anillo de mayor di\u00e1metro encima de uno de\r\n--     menor di\u00e1metro.\r\n-- La leyenda dice que cuando todos los anillos se encuentren en la\r\n-- tercera varilla, ser\u00e1 el fin del mundo.  \r\n-- \r\n-- Definir la funci\u00f3n \r\n--    numPasosHanoi :: Integer -> Integer\r\n-- tal que (numPasosHanoi n) es el n\u00famero de pasos necesarios para\r\n-- trasladar n anillos. Por ejemplo, \r\n--    numPasosHanoi 2   ==  3\r\n--    numPasosHanoi 7   ==  127\r\n--    numPasosHanoi 64  ==  18446744073709551615\r\n-- ---------------------------------------------------------------------\r\n\r\n-- Sean A, B y C las tres varillas. La estrategia recursiva es la\r\n-- siguiente: \r\n-- * Caso base (N=1): Se mueve el disco de A a C.\r\n-- * Caso inductivo (N=M+1): Se mueven M discos de A a C. Se mueve el disco\r\n--   de A a B. Se mueven M discos de C a B.\r\n-- Por tanto,\r\n\r\nnumPasosHanoi :: Integer -> Integer\r\nnumPasosHanoi 1     = 1\r\nnumPasosHanoi (n+1) = 1 + 2 * numPasosHanoi n  \r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 16. (Problema 16 del proyecto Euler) El problema se\r\n-- encuentra en http:\/\/goo.gl\/4uWh y consiste en calcular la suma de las\r\n-- cifras de 2^1000. Lo resolveremos mediante los distintos apartados de\r\n-- este ejercicio.  \r\n-- ---------------------------------------------------------------------\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 16.1. Definir la funci\u00f3n\r\n--    euler16 :: Integer -> Integer\r\n-- tal que (euler16 n) es la suma de las cifras de 2^n. Por ejemplo,\r\n--    euler16 4  ==  7\r\n-- ---------------------------------------------------------------------\r\n\r\neuler16 :: Integer -> Integer\r\neuler16 n = sumaCifrasNR (2^n)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 16.2. Calcular la suma de las cifras de 2^1000.\r\n-- ---------------------------------------------------------------------\r\n\r\n-- El c\u00e1lculo es\r\n--    *Main> euler16 1000\r\n--    1366\r\n<\/pre>\n<p>Los ejercicios, y sus soluciones, de la 7\u00aa relaci\u00f3n se muestran a continuaci\u00f3n:<\/p>\n<pre lang=\"haskell\">\r\n-- I1M 2011-12: Rel_8_sol.hs (21 de Noviembre de 2011)\r\n-- Definiciones por recursi\u00f3n y por comprensi\u00f3n (2)\r\n-- Departamento de Ciencias de la Computaci\u00f3n e I.A.\r\n-- Universidad de Sevilla\r\n-- =====================================================================\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Introducci\u00f3n                                                       --\r\n-- ---------------------------------------------------------------------\r\n\r\n-- En esta relaci\u00f3n se presentan ejercicios con dos definiciones (una\r\n-- por recursi\u00f3n y otra por comprensi\u00f3n) y la comprobaci\u00f3n de la\r\n-- equivalencia de las dos definiciones con QuickCheck. Los ejercicios\r\n-- corresponden a los temas 5 y 6 cuyas transparencias se encuentran en  \r\n--    http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-11\/temas\/tema-5.pdf\r\n--    http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-12\/temas\/tema-6.pdf\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Importaci\u00f3n de librer\u00edas auxiliares                                --\r\n-- ---------------------------------------------------------------------\r\n\r\nimport Test.QuickCheck\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 1.1. Definir, por comprensi\u00f3n, la funci\u00f3n\r\n--    cuadradosC :: [Integer] -> [Integer]\r\n-- tal que (cuadradosC xs) es la lista de los cuadrados de xs. Por\r\n-- ejemplo, \r\n--    cuadradosC [1,2,3]  ==  [1,4,9]\r\n-- ---------------------------------------------------------------------\r\n\r\ncuadradosC :: [Integer] -> [Integer]\r\ncuadradosC xs = [x*x | x <- xs]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 1.2. Definir, por recursi\u00f3n, la funci\u00f3n\r\n--    cuadradosR :: [Integer] -> [Integer]\r\n-- tal que (cuadradosR xs) es la lista de los cuadrados de xs. Por\r\n-- ejemplo, \r\n--    cuadradosR [1,2,3]  ==  [1,4,9]\r\n-- ---------------------------------------------------------------------\r\n\r\ncuadradosR :: [Integer] -> [Integer]\r\ncuadradosR []     = []\r\ncuadradosR (x:xs) = x*x : cuadradosR xs\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 2.1. Definir, por comprensi\u00f3n, la funci\u00f3n\r\n--    imparesC :: [Integer] -> [Integer]\r\n-- tal que (imparesC xs) es la lista de los n\u00fameros impares de xs. Por\r\n-- ejemplo, \r\n--    imparesC [1,2,3]  ==  [1,3]\r\n-- ---------------------------------------------------------------------\r\n\r\nimparesC :: [Integer] -> [Integer]\r\nimparesC xs = [x | x <- xs, odd x]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 2.2. Definir, por recursi\u00f3n, la funci\u00f3n\r\n--    imparesR :: [Integer] -> [Integer]\r\n-- tal que (imparesR xs) es la lista de los n\u00fameros impares de xs. Por\r\n-- ejemplo, \r\n--    imparesR [1,2,3]  ==  [1,3]\r\n-- ---------------------------------------------------------------------\r\n\r\nimparesR :: [Integer] -> [Integer]\r\nimparesR [] = []\r\nimparesR (x:xs) | odd x     = x : imparesR xs\r\n                | otherwise = imparesR xs\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 3.1. Definir, por comprensi\u00f3n, la funci\u00f3n\r\n--    imparesCuadradosC :: [Integer] -> [Integer]\r\n-- tal que (imparesCuadradosC xs) es la lista de los cuadrados de los\r\n-- n\u00fameros impares de xs. Por ejemplo, \r\n--    imparesCuadradosC [1,2,3]  ==  [1,9]\r\n-- ---------------------------------------------------------------------\r\n\r\nimparesCuadradosC :: [Integer] -> [Integer]\r\nimparesCuadradosC xs = [x*x | x <- xs, odd x]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 3.2. Definir, por recursi\u00f3n, la funci\u00f3n\r\n--    imparesCuadradosR :: [Integer] -> [Integer]\r\n-- tal que (imparesCuadradosR xs) es la lista de los cuadrados de los\r\n-- n\u00fameros impares de xs. Por ejemplo, \r\n--    imparesCuadradosR [1,2,3]  ==  [1,9]\r\n-- ---------------------------------------------------------------------\r\n\r\nimparesCuadradosR :: [Integer] -> [Integer]\r\nimparesCuadradosR []                 = []\r\nimparesCuadradosR (x:xs) | odd x     = x*x : imparesCuadradosR xs\r\n                         | otherwise = imparesCuadradosR xs\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 4.1. Definir, por comprensi\u00f3n, la funci\u00f3n\r\n--    sumaCuadradosImparesC :: [Integer] -> Integer\r\n-- tal que (sumaCuadradosImparesC xs) es la suma de los cuadrados de los\r\n-- n\u00fameros impares de la lista xs. Por ejemplo,\r\n--    sumaCuadradosImparesC [1,2,3]  ==  10\r\n-- ---------------------------------------------------------------------\r\n\r\nsumaCuadradosImparesC :: [Integer] -> Integer\r\nsumaCuadradosImparesC xs = sum [ x*x | x <- xs, odd x ]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 4.2. Definir, por recursi\u00f3n, la funci\u00f3n\r\n--    sumaCuadradosImparesR :: [Integer] -> Integer\r\n-- tal que (sumaCuadradosImparesR xs) es la suma de los cuadrados de los\r\n-- n\u00fameros impares de la lista xs. Por ejemplo,\r\n--    sumaCuadradosImparesR [1,2,3]  ==  10\r\n-- ---------------------------------------------------------------------\r\n\r\nsumaCuadradosImparesR :: [Integer] -> Integer\r\nsumaCuadradosImparesR []                  = 0\r\nsumaCuadradosImparesR (x:xs) \r\n    | odd x     = x*x + sumaCuadradosImparesR xs\r\n    | otherwise = sumaCuadradosImparesR xs\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 5.1. Definir, usando funciones predefinidas, la funci\u00f3n\r\n--    entreL :: Integer -> Integer -> [Integer]\r\n-- tal que (entreL m n) es la lista de los n\u00fameros entre m y n. Por\r\n-- ejemplo, \r\n--    entreL 2 5  ==  [2,3,4,5]\r\n-- ---------------------------------------------------------------------\r\n\r\nentreL :: Integer -> Integer -> [Integer]\r\nentreL m n = [m..n]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 5.2. Definir, por recursi\u00f3n, la funci\u00f3n\r\n--    entreR :: Integer -> Integer -> [Integer]\r\n-- tal que (entreR m n) es la lista de los n\u00fameros entre m y n. Por\r\n-- ejemplo, \r\n--    entreR 2 5  ==  [2,3,4,5]\r\n-- ---------------------------------------------------------------------\r\n\r\nentreR :: Integer -> Integer -> [Integer]\r\nentreR m n | m > n     = []\r\n           | otherwise = m : entreR (m+1) n\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 6.1. Definir, por comprensi\u00f3n, la funci\u00f3n\r\n--    mitadPares :: [Int] -> [Int]\r\n-- tal que (mitadPares xs) es la lista de las mitades de los elementos\r\n-- de xs que son pares. Por ejemplo,\r\n--    mitadPares [0,2,1,7,8,56,17,18]  ==  [0,1,4,28,9]\r\n-- ---------------------------------------------------------------------\r\n\r\nmitadPares :: [Int] -> [Int]\r\nmitadPares xs = [x `div` 2 | x <- xs, x `mod` 2 == 0]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 6.2. Definir, por recursi\u00f3n, la funci\u00f3n\r\n--    mitadParesRec :: [Int] -> [Int]\r\n-- tal que (mitadParesRec []) es la lista de las mitades de los elementos\r\n-- de xs que son pares. Por ejemplo,\r\n--    mitadParesRec [0,2,1,7,8,56,17,18]  ==  [0,1,4,28,9]\r\n-- ---------------------------------------------------------------------\r\n\r\nmitadParesRec :: [Int] -> [Int]\r\nmitadParesRec [] = []\r\nmitadParesRec (x:xs)\r\n    | even x    = x `div` 2 : mitadParesRec xs\r\n    | otherwise = mitadParesRec xs\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 6.3. Comprobar con QuickCheck que ambas definiciones son\r\n-- equivalentes. \r\n-- ---------------------------------------------------------------------\r\n\r\n-- La propiedad es\r\nprop_mitadPares :: [Int] -> Bool\r\nprop_mitadPares xs = \r\n    mitadPares xs == mitadParesRec xs\r\n\r\n-- La comprobaci\u00f3n es\r\n--    ghci> quickCheck prop_mitadPares\r\n--    +++ OK, passed 100 tests.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 7.1. Definir, por comprensi\u00f3n, la funci\u00f3n\r\n--    enRango :: Int -> Int -> [Int] -> [Int]\r\n-- tal que (enRango a b xs) es la lista de los elementos de xs mayores o\r\n-- iguales que a y menores o iguales que b. Por ejemplo,\r\n--    enRango  5 10 [1..15]   ==  [5,6,7,8,9,10]\r\n--    enRango 10  5 [1..15]   ==  []\r\n--    enRango  5  5 [1..15]   ==  [5]\r\n-- ---------------------------------------------------------------------\r\n\r\nenRango :: Int -> Int -> [Int] -> [Int]\r\nenRango a b xs = [x | x <- xs, a <= x, x <= b]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 7.2. Definir, por recursi\u00f3n, la funci\u00f3n\r\n--    enRangoRec :: Int -> Int -> [Int] -> [Int]\r\n-- tal que (enRangoRec a b []) es la lista de los elementos de xs\r\n-- mayores o iguales que a y menores o iguales que b. Por ejemplo,\r\n--    enRangoRec  5 10 [1..15]  ==  [5,6,7,8,9,10]\r\n--    enRangoRec 10 5 [1..15]   ==  []\r\n--    enRangoRec  5 5 [1..15]   ==  [5]\r\n-- ---------------------------------------------------------------------\r\n\r\nenRangoRec :: Int -> Int -> [Int] -> [Int]\r\nenRangoRec a b [] = []\r\nenRangoRec a b (x:xs)\r\n    | a <= x &#038;&#038; x <= b  = x : enRangoRec a b xs\r\n    | otherwise         = enRangoRec a b xs\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 7.3. Comprobar con QuickCheck que ambas definiciones son\r\n-- equivalentes. \r\n-- ---------------------------------------------------------------------\r\n\r\n-- La propiedad es\r\nprop_enRango :: Int -> Int -> [Int] -> Bool\r\nprop_enRango a b xs = \r\n    enRango a b xs == enRangoRec a b xs\r\n\r\n-- La comprobaci\u00f3n es\r\n--    ghci> quickCheck prop_enRango\r\n--    +++ OK, passed 100 tests.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 8.1. Definir, por comprensi\u00f3n, la funci\u00f3n\r\n--    sumaPositivos :: [Int] -> Int\r\n-- tal que (sumaPositivos xs) es la suma de los n\u00fameros positivos de\r\n-- xs. Por ejemplo, \r\n--    sumaPositivos [0,1,-3,-2,8,-1,6]  ==  15\r\n-- ---------------------------------------------------------------------\r\n\r\nsumaPositivos :: [Int] -> Int\r\nsumaPositivos xs = sum [x | x <- xs, x > 0]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 8.2. Definir, por recursi\u00f3n, la funci\u00f3n\r\n--    sumaPositivosRec :: [Int] -> Int\r\n-- tal que (sumaPositivosRec xs) es la suma de los n\u00fameros positivos de\r\n-- xs. Por ejemplo, \r\n--    sumaPositivosRec [0,1,-3,-2,8,-1,6]  ==  15\r\n-- ---------------------------------------------------------------------\r\n\r\nsumaPositivosRec :: [Int] -> Int\r\nsumaPositivosRec [] = 0\r\nsumaPositivosRec (x:xs) | x > 0     = x + sumaPositivosRec xs\r\n                        | otherwise = sumaPositivosRec xs\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 8.3. Comprobar con QuickCheck que ambas definiciones son\r\n-- equivalentes. \r\n-- ---------------------------------------------------------------------\r\n\r\n-- La propiedad es\r\nprop_sumaPositivos :: [Int] -> Bool\r\nprop_sumaPositivos xs = \r\n    sumaPositivos xs == sumaPositivosRec xs\r\n\r\n-- La comprobaci\u00f3n es\r\n--    ghci> quickCheck prop_sumaPositivos\r\n--    +++ OK, passed 100 tests.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 9. El doble factorial de un n\u00famero n se define por \r\n--    n!! = n*(n-2)* ... * 3 * 1, si n es impar\r\n--    n!! = n*(n-2)* ... * 4 * 2, si n es par\r\n--    1!! = 1\r\n--    0!! = 1    \r\n-- Por ejemplo,\r\n--    8!! = 8*6*4*2   = 384\r\n--    9!! = 9*7*5*3*1 = 945\r\n-- Definir, por recursi\u00f3n, la funci\u00f3n\r\n--    dobleFactorial :: Integer -> Integer\r\n-- tal que (dobleFactorial n) es el doble factorial de n. Por ejemplo,\r\n--    dobleFactorial 8  ==  384\r\n--    dobleFactorial 9  ==  945\r\n-- ---------------------------------------------------------------------\r\n\r\ndobleFactorial :: Integer -> Integer\r\ndobleFactorial 0 = 1\r\ndobleFactorial 1 = 1\r\ndobleFactorial n = n * dobleFactorial (n-2)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 10. Definir, por comprensi\u00f3n, la funci\u00f3n\r\n--    sumaConsecutivos :: [Int] -> [Int]\r\n-- tal que (sumaConsecutivos xs) es la suma de los pares de elementos\r\n-- consecutivos de la lista xs. Por ejemplo,\r\n--    sumaConsecutivos [3,1,5,2]  ==  [4,6,7]\r\n--    sumaConsecutivos [3]        ==  []\r\n-- ---------------------------------------------------------------------\r\n\r\nsumaConsecutivos :: [Int] -> [Int]\r\nsumaConsecutivos xs = [x+y | (x,y) <- zip xs (tail xs)]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 11. La distancia de Hamming entre dos listas es el\r\n-- n\u00famero de posiciones en que los correspondientes elementos son\r\n-- distintos. Por ejemplo, la distancia de Hamming entre \"roma\" y \"loba\"\r\n-- es 2 (porque hay 2 posiciones en las que los elementos\r\n-- correspondientes son distintos: la 1\u00aa y la 3\u00aa).\r\n--    \r\n-- Definir la funci\u00f3n\r\n--    distancia :: Eq a => [a] -> [a] -> Int\r\n-- tal que (distancia xs ys) es la distancia de Hamming entre xs e\r\n-- ys. Por ejemplo,\r\n--    distancia \"romano\" \"comino\"  ==  2\r\n--    distancia \"romano\" \"camino\"  ==  3\r\n--    distancia \"roma\"   \"comino\"  ==  2\r\n--    distancia \"roma\"   \"camino\"  ==  3\r\n--    distancia \"romano\" \"ron\"     ==  1\r\n--    distancia \"romano\" \"cama\"    ==  2\r\n--    distancia \"romano\" \"rama\"    ==  1\r\n-- ---------------------------------------------------------------------\r\n\r\n-- Por comprensi\u00f3n:\r\ndistancia :: Eq a => [a] -> [a] -> Int\r\ndistancia xs ys = length [(x,y) | (x,y) <- zip xs ys, x \/= y] \r\n\r\n-- Por recursi\u00f3n:\r\ndistancia' :: Eq a => [a] -> [a] -> Int\r\ndistancia' [] ys = 0\r\ndistancia' xs [] = 0\r\ndistancia' (x:xs) (y:ys) | x \/= y    = 1 + distancia' xs ys\r\n                         | otherwise = distancia' xs ys\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 12. La suma de la serie\r\n--    1\/1^2 + 1\/2^2 + 1\/3^2 + 1\/4^2 + ...\r\n-- es pi^2\/6. Por tanto, pi se puede aproximar mediante la ra\u00edz cuadrada\r\n-- de 6 por la suma de la serie.\r\n-- \r\n-- Definir la funci\u00f3n aproximaPi tal que (aproximaPi n) es la aproximaci\u00f3n \r\n-- de pi obtenida mediante n t\u00e9rminos de la serie. Por ejemplo, \r\n--    aproximaPi 4    == sqrt(6*(1\/1^2 + 1\/2^2 + 1\/3^2 + 1\/4^2))\r\n--                    == 2.9226129861250305\r\n--    aproximaPi 1000 == 3.1406380562059946\r\n-- ---------------------------------------------------------------------\r\n\r\n-- Por comprensi\u00f3n:\r\naproximaPi n = sqrt(6*sum [1\/x^2 | x <- [1..n]])\r\n\r\n-- Por recursi\u00f3n:\r\naproximaPi' n = sqrt(6*aproximaPi'' n)\r\n\r\naproximaPi'' 1 = 1\r\naproximaPi'' n = 1\/n^2 + aproximaPi'' (n-1)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 13.1. Definir por recursi\u00f3n la funci\u00f3n \r\n--    sustituyeImpar :: [Int] -> [Int]\r\n-- tal que (sustituyeImpar xs) es la lista obtenida sustituyendo cada\r\n-- n\u00famero impar de xs por el siguiente n\u00famero par. Por ejemplo,\r\n--    sustituyeImpar [2,5,7,4]  ==  [2,6,8,4]\r\n-- --------------------------------------------------------------------- \r\n\r\nsustituyeImpar :: [Int] -> [Int]\r\nsustituyeImpar []     = []\r\nsustituyeImpar (x:xs) | odd x     = (x+1): sustituyeImpar xs\r\n                      | otherwise = x:sustituyeImpar xs\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 13.2. Comprobar con QuickChek la siguiente propiedad: para\r\n-- cualquier lista de n\u00fameros enteros xs, todos los elementos de la\r\n-- lista (sustituyeImpar xs) son n\u00fameros pares. \r\n-- ---------------------------------------------------------------------\r\n\r\n-- La propiedad es\r\nprop_sustituyeImpar :: [Int] -> Bool\r\nprop_sustituyeImpar xs = and [even x | x <- sustituyeImpar xs]\r\n\r\n-- La comprobaci\u00f3n es\r\n--    ghci> quickCheck prop_sustituyeImpar\r\n--    +++ OK, passed 100 tests.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 14.1. El n\u00famero e se puede definir como la suma de la\r\n-- serie: \r\n--    1\/0! + 1\/1! + 1\/2! + 1\/3! +...\r\n-- Definir la funci\u00f3n aproxE tal que (aproxE n) es la aproximaci\u00f3n de e\r\n-- que se obtiene sumando los t\u00e9rminos de la serie hasta 1\/n!. Por\r\n-- ejemplo, \r\n--    aproxE 10  ==  2.718281801146385\r\n--    aproxE 100  ==  2.7182818284590455\r\n-- ---------------------------------------------------------------------\r\n\r\naproxE n = 1 + sum [ 1 \/ factorial k | k <- [1..n]]\r\n\r\nfactorial n = product [1..n]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 14.2. Definir la constante e como 2.71828459.\r\n-- ---------------------------------------------------------------------\r\n\r\ne = 2.71828459\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 14.3. Definir la funci\u00f3n errorE tal que (errorE x) es el\r\n-- menor n\u00famero de t\u00e9rminos de la serie anterior necesarios para obtener\r\n-- e con un error menor que x.  \r\n--    errorE 0.1     ==  3.0\r\n--    errorE 0.01    ==  4.0\r\n--    errorE 0.001   ==  6.0\r\n--    errorE 0.0001  ==  7.0\r\n-- ---------------------------------------------------------------------\r\n\r\nerrorE x = head [n | n <- [0..], abs(aproxE n - e) < x]\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>La clase de hoy de Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas hemos terminado continuado comentando soluciones de ejercicios con definiciones por recursi\u00f3n y comprensi\u00f3n. Concretamente, hemos visto los la 7\u00aa relaci\u00f3n (que comenzamos en la clase del d\u00eda 22 y continuamos en la clase del 25) y los de la 8\u00aa relaci\u00f3n. Los ejercicios,&#8230;<\/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":[186,1],"tags":[295],"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\/1721"}],"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=1721"}],"version-history":[{"count":5,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/1721\/revisions"}],"predecessor-version":[{"id":2899,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/1721\/revisions\/2899"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=1721"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=1721"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=1721"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}