{"id":5123,"date":"2015-10-23T16:09:32","date_gmt":"2015-10-23T14:09:32","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=5123"},"modified":"2015-10-23T16:09:33","modified_gmt":"2015-10-23T14:09:33","slug":"i1m2015-ejercicios-de-definiciones-por-recursion","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/i1m2015-ejercicios-de-definiciones-por-recursion\/","title":{"rendered":"I1M2015: Ejercicios de definiciones por recursi\u00f3n"},"content":{"rendered":"<p>En la segunda parte de la clase de hoy del curso de <a href=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-15\">Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas<\/a> se han comentado las soluciones de los ejercicios de la 5\u00aa relaci\u00f3n sobre definiciones por recursi\u00f3n.<\/p>\n<p>Los ejercicios y sus soluciones 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-- recursi\u00f3n correspondientes al tema 6 cuyas transparencias se \n-- encuentran en  \n--    http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-15\/temas\/tema-6.html\n \n-- ---------------------------------------------------------------------\n-- Importaci\u00f3n de librer\u00edas auxiliares                                --\n-- ---------------------------------------------------------------------\n\nimport Test.QuickCheck\nimport Data.List\nimport Data.Char\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 1.1. Definir por recursi\u00f3n la funci\u00f3n\n--    potencia :: Integer -> Integer -> Integer\n-- tal que (potencia x n) es x elevado al n\u00famero natural n. Por ejemplo,  \n--    potencia 2 3  ==  8\n-- ---------------------------------------------------------------------\n\npotencia :: Integer -> Integer -> Integer\npotencia m 0 = 1\npotencia m n = m*(potencia m (n-1))\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 1.2. Comprobar con QuickCheck que la funci\u00f3n potencia es\n-- equivalente a la predefinida (^).\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_potencia :: Integer -> Integer -> Property\nprop_potencia x n = \n    n >= 0 ==> potencia x n == x^n\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_potencia\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 2.1. Dados dos n\u00fameros naturales, a y b, es posible\n-- calcular su m\u00e1ximo com\u00fan divisor mediante el Algoritmo de\n-- Euclides. Este algoritmo se puede resumir en la siguiente f\u00f3rmula:\n--    mcd(a,b) = a,                   si b = 0\n--             = mcd (b, a m\u00f3dulo b), si b > 0\n-- \n-- Definir la funci\u00f3n \n--    mcd :: Integer -> Integer -> Integer\n-- tal que (mcd a b) es el m\u00e1ximo com\u00fan divisor de a y b calculado\n-- mediante el algoritmo de Euclides. Por ejemplo,\n--    mcd 30 45  ==  15\n-- ---------------------------------------------------------------------\n\nmcd :: Integer -> Integer -> Integer\nmcd a 0 = a\nmcd a b = mcd b (a `mod` b)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 2.2. Definir y comprobar la propiedad prop_mcd seg\u00fan la\n-- cual el m\u00e1ximo com\u00fan divisor de dos n\u00fameros a y b (ambos mayores que\n-- 0) es siempre mayor o igual que 1 y adem\u00e1s es menor o igual que el\n-- menor de los n\u00fameros a  y b. \n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_mcd :: Integer -> Integer -> Property\nprop_mcd a b =\n    a > 0 && b > 0 ==> m >= 1 && m <= min a b \n    where m = mcd a b\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_mcd\n--    OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 2.3. Teniendo en cuenta que buscamos el m\u00e1ximo com\u00fan\n-- divisor de a y b, ser\u00eda razonable pensar que el m\u00e1ximo com\u00fan divisor\n-- siempre ser\u00eda igual o menor que la mitad del m\u00e1ximo de a y b. Definir\n-- esta propiedad y comprobarla.  \n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_mcd_div :: Integer -> Integer -> Property\nprop_mcd_div a b =\n    a > 0 && b > 0 ==> mcd a b <= (max a b) `div` 2\n\n-- Al verificarla, se obtiene\n--    ghci> quickCheck prop_mcd_div\n--    Falsifiable, after 0 tests:\n--    3\n--    3\n-- que la refuta. Pero si la modificamos a\u00f1adiendo la hip\u00f3tesis que los n\u00fameros\n-- son distintos,\nprop_mcd_div' :: Integer -> Integer -> Property\nprop_mcd_div' a b =\n    a > 0 && b > 0 && a \/= b ==> mcd a b <= (max a b) `div` 2\n\n-- entonces al comprobarla\n--    ghci> quickCheck prop_mcd_div'\n--    OK, passed 100 tests.\n-- obtenemos que se verifica.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3.1, Definir por recursi\u00f3n la funci\u00f3n\n--    pertenece :: Eq a => a -> [a] -> Bool\n-- tal que (pertenece x xs) se verifica si x pertenece a la lista xs. Por\n-- ejemplo, \n--    pertenece 3 [2,3,5]  ==  True\n--    pertenece 4 [2,3,5]  ==  False\n-- ---------------------------------------------------------------------\n\npertenece :: Eq a => a -> [a] -> Bool\npertenece _ []     = False\npertenece x (y:ys) = x == y || pertenece x ys\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3.2. Comprobar con quickCheck que pertenece es equivalente\n-- a elem. \n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_pertenece :: Eq a => a -> [a] -> Bool\nprop_pertenece x xs = pertenece x xs == elem x xs\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_pertenece\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 4.1. Definir por recursi\u00f3n la funci\u00f3n\n--    concatenaListas :: [[a]] -> [a]\n-- tal que (concatenaListas xss) es la lista obtenida concatenando las listas de\n-- xss. Por ejemplo,\n--    concatenaListas [[1..3],[5..7],[8..10]]  ==  [1,2,3,5,6,7,8,9,10]\n-- ---------------------------------------------------------------------\n \nconcatenaListas :: [[a]] -> [a]\nconcatenaListas []       = []\nconcatenaListas (xs:xss) = xs ++ concatenaListas xss\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 4.2. Comprobar con QuickCheck que concatenaListas es\n-- equivalente a concat. \n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_concat :: Eq a => [[a]] -> Bool\nprop_concat xss = concatenaListas xss == concat xss\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_concat\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 5.1. Definir por recursi\u00f3n la funci\u00f3n\n--    coge :: Int -> [a] -> [a]\n-- tal que (coge n xs) es la lista de los n primeros elementos de\n-- xs. Por ejemplo, \n--    coge 3 [4..12]  =>  [4,5,6]\n-- ---------------------------------------------------------------------\n\ncoge :: Int -> [a] -> [a]\ncoge n _  | n <= 0 = []\ncoge n []          = []\ncoge n (x:xs)      = x : coge (n-1) xs\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 5.2. Comprobar con QuickCheck que coge es equivalente a\n-- take. \n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_coge :: Int -> [Int] -> Bool\nprop_coge n xs =\n    coge n xs == take n xs\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 6.1. Definir, por recursi\u00f3n, la funci\u00f3n \n--    sumaCuadradosR :: Integer -> Integer\n-- tal que (sumaCuadradosR n) es la suma de los cuadrados de los n\u00fameros\n-- de 1 a n. Por ejemplo, \n--    sumaCuadradosR 4  ==  30 \n-- ---------------------------------------------------------------------\n\nsumaCuadradosR :: Integer -> Integer\nsumaCuadradosR 0 = 0\nsumaCuadradosR n = n^2 + sumaCuadradosR (n-1) \n\n-- ---------------------------------------------------------------------\n-- Ejercicio 6.2. Comprobar con QuickCheck si sumaCuadradosR n es igual a\n-- n(n+1)(2n+1)\/6. \n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_SumaCuadrados :: Integer -> Property\nprop_SumaCuadrados n =\n  n >= 0 ==>\n    sumaCuadradosR n == n * (n+1) * (2*n+1) `div` 6  \n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_SumaCuadrados\n--    OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 6.3. Definir, por comprensi\u00f3n, la funci\u00f3n \n--    sumaCuadradosC :: Integer --> Integer\n-- tal que (sumaCuadradosC n) es la suma de los cuadrados de los n\u00fameros\n-- de 1 a n. Por ejemplo, \n--    sumaCuadradosC 4  ==  30 \n-- ---------------------------------------------------------------------\n\nsumaCuadradosC :: Integer -> Integer\nsumaCuadradosC n = sum [x^2 | x <- [1..n]]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 6.4. Comprobar con QuickCheck que las funciones\n-- sumaCuadradosR y sumaCuadradosC son equivalentes sobre los n\u00fameros\n-- naturales. \n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_sumaCuadradosR :: Integer -> Property\nprop_sumaCuadradosR n =\n    n >= 0 ==> sumaCuadradosR n == sumaCuadradosC n\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_sumaCuadrados\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 7.1. Definir, por recursi\u00f3n, la funci\u00f3n\n--    digitosR :: Integer -> [Integer]\n-- tal que (digitosR n) es la lista de los d\u00edgitos del n\u00famero n. Por\n-- ejemplo, \n--    digitosR 320274  ==  [3,2,0,2,7,4]\n-- ---------------------------------------------------------------------\n\ndigitosR :: Integer -> [Integer]\ndigitosR n = reverse (digitosR' n)\n\ndigitosR' n\n    | n < 10    = [n]\n    | otherwise = (n `rem` 10) : digitosR' (n `div` 10)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 7.2. Definir, por comprensi\u00f3n, la funci\u00f3n\n--    digitosC :: Integer -> [Integer]\n-- tal que (digitosC n) es la lista de los d\u00edgitos del n\u00famero n. Por\n-- ejemplo, \n--    digitosC 320274  ==  [3,2,0,2,7,4]\n-- Indicaci\u00f3n: Usar las funciones show y read.\n-- ---------------------------------------------------------------------\n\ndigitosC :: Integer -> [Integer]\ndigitosC n = [read [x] | x <- show n]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 7.3. Comprobar con QuickCheck que las funciones digitosR y\n-- digitosC son equivalentes.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_digitos :: Integer -> Property\nprop_digitos n =\n    n >= 0 ==> \n    digitosR n == digitosC n\n  \n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_digitos\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 8.1. Definir, por recursi\u00f3n, la funci\u00f3n \n--    sumaDigitosR :: Integer -> Integer\n-- tal que (sumaDigitosR n) es la suma de los d\u00edgitos de n. Por ejemplo,\n--    sumaDigitosR 3     ==  3\n--    sumaDigitosR 2454  == 15\n--    sumaDigitosR 20045 == 11\n-- ---------------------------------------------------------------------\n\nsumaDigitosR :: Integer -> Integer\nsumaDigitosR n\n    | n < 10    = n\n    | otherwise = n `rem` 10 + sumaDigitosR (n `div` 10)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 8.2. Definir, sin usar recursi\u00f3n, la funci\u00f3n \n--    sumaDigitosNR :: Integer -> Integer\n-- tal que (sumaDigitosNR n) es la suma de los d\u00edgitos de n. Por ejemplo,\n--    sumaDigitosNR 3     ==  3\n--    sumaDigitosNR 2454  == 15\n--    sumaDigitosNR 20045 == 11\n-- ---------------------------------------------------------------------\n\nsumaDigitosNR :: Integer -> Integer\nsumaDigitosNR n = sum (digitosC n)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 8.3. Comprobar con QuickCheck que las funciones sumaDigitosR\n-- y sumaDigitosNR son equivalentes.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_sumaDigitos :: Integer -> Property\nprop_sumaDigitos n =\n    n >= 0 ==>\n    sumaDigitosR n == sumaDigitosNR n\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_sumaDigitos\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 9.1. Definir, por recursi\u00f3n, la funci\u00f3n \n--    listaNumeroR :: [Integer] -> Integer\n-- tal que (listaNumeroR xs) es el n\u00famero formado por los d\u00edgitos xs. Por\n-- ejemplo, \n--    listaNumeroR [5]        == 5\n--    listaNumeroR [1,3,4,7]  == 1347\n--    listaNumeroR [0,0,1]    == 1\n-- ---------------------------------------------------------------------\n\nlistaNumeroR :: [Integer] -> Integer\nlistaNumeroR xs = listaNumeroR' (reverse xs)\n\nlistaNumeroR' :: [Integer] -> Integer\nlistaNumeroR' []     = 0\nlistaNumeroR' (x:xs) = x + 10 * (listaNumeroR' xs)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 9.2. Definir, por comprensi\u00f3n, la funci\u00f3n \n--    listaNumeroC :: [Integer] -> Integer\n-- tal que (listaNumeroC xs) es el n\u00famero formado por los d\u00edgitos xs. Por\n-- ejemplo, \n--    listaNumeroC [5]        == 5\n--    listaNumeroC [1,3,4,7]  == 1347\n--    listaNumeroC [0,0,1]    == 1\n-- ---------------------------------------------------------------------\n\n-- 1\u00aa definici\u00f3n:\nlistaNumeroC :: [Integer] -> Integer\nlistaNumeroC xs = sum [y*10^n | (y,n) <- zip (reverse xs) [0..]]\n\n-- 2\u00aa definici\u00f3n:\nlistaNumeroC2 :: [Integer] -> Integer\nlistaNumeroC2 xs = read [x | x <- show xs, isDigit x]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 9.3. Comprobar con QuickCheck que las funciones\n-- listaNumeroR y listaNumeroC son equivalentes.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_listaNumero :: [Integer] -> Bool\nprop_listaNumero xs =\n    listaNumeroR xs == listaNumeroC xs\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_listaNumero\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 10. Definir la funci\u00f3n \n--    capicua :: Integer -> Bool\n-- tal que (capicua n) se verifica si los d\u00edgitos que n son las mismos\n-- de izquierda a derecha que de derecha a izquierda. Por ejemplo,\n--    capicua 1234  =  False\n--    capicua 1221  =  True\n--    capicua 4     =  True\n-- ---------------------------------------------------------------------\n\ncapicua :: Integer -> Bool\ncapicua n = show n == reverse (show n)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 11.1. Definir, por recursi\u00f3n, la funci\u00f3n \n--    mayorExponenteR :: Integer -> Integer -> Integer \n-- tal que (mayorExponenteR a b) es el exponente de la mayor potencia de\n-- a que divide b. Por ejemplo,\n--    mayorExponenteR 2 8    ==  3\n--    mayorExponenteR 2 9    ==  0\n--    mayorExponenteR 5 100  ==  2\n--    mayorExponenteR 2 60   ==  2\n-- ---------------------------------------------------------------------\n\nmayorExponenteR :: Integer -> Integer -> Integer \nmayorExponenteR a b\n    | rem b a \/= 0 = 0\n    | otherwise    = 1 + mayorExponenteR a (b `div` a)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 11.2. Definir, por comprensi\u00f3n, la funci\u00f3n \n--    mayorExponenteC :: Integer -> Integer -> Integer \n-- tal que (mayorExponenteC a b) es el exponente de la mayor potencia de\n-- a que divide a b. Por ejemplo,\n--    mayorExponenteC 2 8    ==  3\n--    mayorExponenteC 5 100  ==  2\n--    mayorExponenteC 5 101  ==  0\n-- ---------------------------------------------------------------------\n\nmayorExponenteC :: Integer -> Integer -> Integer\nmayorExponenteC a b = head [x-1 | x <- [0..], mod b (a^x) \/= 0]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 12.1. La suma de la serie\n--    1\/1^2 + 1\/2^2 + 1\/3^2 + 1\/4^2 + ...\n-- es pi^2\/6. Por tanto, pi se puede aproximar mediante la ra\u00edz cuadrada\n-- de 6 por la suma de la serie.\n-- \n-- Definir, por comprensi\u00f3n, la funci\u00f3n aproximaPiC tal que \n-- (aproximaPiC n) es la aproximaci\u00f3n  de pi obtenida mediante n\n-- t\u00e9rminos de la serie. Por ejemplo,  \n--    aproximaPiC 4    == sqrt(6*(1\/1^2 + 1\/2^2 + 1\/3^2 + 1\/4^2))\n--                     == 2.9226129861250305\n--    aproximaPiC 1000 == 3.1406380562059946\n-- ---------------------------------------------------------------------\n\naproximaPiC n = sqrt (6*sum [1\/x^2 | x <- [1..n]])\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 12.2. Definir, por recursi\u00f3n, la funci\u00f3n aproximaPiR tal\n-- que (aproximaPiR n) es la aproximaci\u00f3n  de pi obtenida mediante n\n-- t\u00e9rminos de la serie. Por ejemplo,  \n--    aproximaPiR 4    == sqrt(6*(1\/1^2 + 1\/2^2 + 1\/3^2 + 1\/4^2))\n--                     == 2.9226129861250305\n--    aproximaPiR 1000 == 3.1406380562059946\n-- ---------------------------------------------------------------------\n\naproximaPiR n = sqrt(6*aproximaPiR' n)\n\naproximaPiR' 1 = 1\naproximaPiR' n = 1\/n^2 + aproximaPiR' (n-1)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 13.1. Comprobar con QuickCheck si la funci\u00f3n mcd definida\n-- en el ejercicio 2.1 es equivalente a la funci\u00f3n gcd\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_mcd_gcd :: Integer -> Integer -> Bool\nprop_mcd_gcd a b =\n    mcd a b == gcd a b\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_mcd_gcd\n--    *** Failed! Falsifiable (after 5 tests and 2 shrinks): \n--    0\n--    -1\n-- Efectivamente, \n--    ghci> mcd 0 (-1)\n--    -1\n--    ghci> gcd 0 (-1)\n--    1\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 13.2. Definir la funci\u00f3n \n--    mcdE :: Integer -> Integer -> Integer\n-- tal que (mcdE a b) es el m\u00e1ximo com\u00fan divisor de a y b calculado\n-- mediante el algoritmo de Euclides, pero extendido a los n\u00fameros\n-- negativos. Por ejemplo, \n--    mcdE 30 45  ==  15\n--    mcdE (-2) 0 ==  2\n--    mcdE (-4) 6 ==  2 \n--    mcdE 0 4    ==  4 \n--    mcdE 0 0    ==  0\n-- ---------------------------------------------------------------------\n\nmcdE :: Integer -> Integer -> Integer\nmcdE a 0 = abs a\nmcdE a b = mcdE b (a `mod` b)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 13.3. Comprobar con QuickCheck si las funciones mcdE  y gcd\n-- son equivalentes. \n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_mcdE_gcd :: Integer -> Integer -> Bool\nprop_mcdE_gcd a b =\n    mcdE a b == gcd a b\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_mcdE_gcd\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 13.4. Comprobar con QuickCheck que (mcd a b) es un divisor\n-- de a y de b.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_mcdE_esDivisor :: Integer -> Integer -> Property\nprop_mcdE_esDivisor a b =\n    a > 0 && b > 0 ==> a `rem` m == 0 && b `rem` m == 0\n    where m = mcdE a b\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_mcdE_esDivisor\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 13.4. Comprobar con QuickCheck que todos los divisores\n-- comunes de a y b son divisores de (mcdE a b).\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_mcdE_esMaximo :: Integer -> Integer -> Integer -> Property\nprop_mcdE_esMaximo a b c =\n    a > 0 && b > 0 && c \/= 0 && divide c a && divide c b\n    ==> divide c (mcdE a b) \n    where divide x y = rem y x == 0\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_mcdE_esMaximo\n--    *** Gave up! Passed only 26 tests.\n\n-- La propiedad es\nprop_mcdE_esMaximo2 :: Integer -> Integer -> Integer -> Property\nprop_mcdE_esMaximo2 a b c =\n    a > 0 && b > 0 \n    ==> and [divide x (mcdE a b) | x <- divisores a, divide x b]\n    \n-- (divide x y) se verifica si x divide a y. Por ejemplo,\n--    divide 2 6  ==  True\n--    divide 2 7  ==  False\ndivide :: Integer -> Integer -> Bool\ndivide x y  = rem y x == 0\n\n-- (divisores x) es la lista de los divisores de x. Por ejemplo,\n--    divisores 90  ==  [1,2,3,5,6,9,10,15,18,30,45,90]\ndivisores :: Integer -> [Integer]\ndivisores x = [y | y <- [1..x], divide y x]\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_mcdE_esMaximo2\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 14.1. Definir, por comprensi\u00f3n, la funci\u00f3n \n--    mcdC :: Integer -> Integer -> Integer\n-- tal que (mcdC a b) es el m\u00e1ximo com\u00fan divisor de a y b. Por ejemplo, \n--    mcdC 30 45  ==  15\n--    mcdC (-2) 0 ==  2\n--    mcdC (-4) 6 ==  2 \n--    mcdC 0 4    ==  4 \n--    mcdC 0 0    ==  0\n-- ---------------------------------------------------------------------\n\nmcdC :: Integer -> Integer -> Integer\nmcdC 0 b = abs b\nmcdC a b = head [x | x <- [c,c-1..1], divide x a, divide x b]\n    where c = min (abs a) (abs b)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 14.2. Comprobar con QuickCheck si las funciones mcdC  y gcd\n-- son equivalentes. \n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_mcdC_gcd :: Integer -> Integer -> Bool\nprop_mcdC_gcd a b =\n    mcdC a b == gcd a b\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_mcdC_gcd\n--    +++ OK, passed 100 tests.\n<\/pre>\n<p>El c\u00f3digo anterior se encuentra tambi\u00e9n en <a href=\"http:\/\/bit.ly\/1Ma6MYB\">GitHub<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>En la segunda parte de la clase de hoy del curso de Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas se han comentado las soluciones de los ejercicios de la 5\u00aa relaci\u00f3n sobre definiciones por recursi\u00f3n. Los ejercicios y sus soluciones se muestran a continuaci\u00f3n<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","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":[250],"tags":[270,310],"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\/5123"}],"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=5123"}],"version-history":[{"count":1,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/5123\/revisions"}],"predecessor-version":[{"id":5124,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/5123\/revisions\/5124"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=5123"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=5123"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=5123"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}