{"id":2387,"date":"2012-12-03T12:25:54","date_gmt":"2012-12-03T12:25:54","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=2387"},"modified":"2013-03-08T05:47:37","modified_gmt":"2013-03-08T05:47:37","slug":"i1m2011-ejercicios-de-definiciones-por-recursion-y-comprension-en-haskell-2","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/i1m2011-ejercicios-de-definiciones-por-recursion-y-comprension-en-haskell-2\/","title":{"rendered":"I1M2011: Ejercicios de definiciones por recursi\u00f3n y comprensi\u00f3n en Haskell (2)"},"content":{"rendered":"<p>En la clase de hoy de <a href=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-12\">Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas<\/a> hemos comentado las soluciones de los ejercicios 8 a 13 de la <a href=\"https:\/\/www.glc.us.es\/~jalonso\/ejerciciosI1M2012G2\/images\/6\/6c\/Rel_9.hs\">9\u00aa relaci\u00f3n<\/a> en la que se presentan ejercicios con dos definiciones (una por recursi\u00f3n y otra por comprensi\u00f3n) y la comprobaci\u00f3n de la equivalencia de las dos definiciones con QuickCheck. <\/p>\n<p>Los ejercicios, y sus soluciones, se muestran a continuaci\u00f3n:<br \/>\n<!--more--><\/p>\n<pre lang=\"haskell\">\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 4.1. Definir, por recursi\u00f3n, la funci\u00f3n\r\n--    digitosR :: Integer -> [Integer]\r\n-- tal que (digitosR n) es la lista de los d\u00edgitos del n\u00famero n. Por\r\n-- ejemplo, \r\n--    digitosR 320274  ==  [3,2,0,2,7,4]\r\n-- ---------------------------------------------------------------------\r\n\r\ndigitosR :: Integer -> [Integer]\r\ndigitosR n = reverse (digitosR' n)\r\n\r\ndigitosR' n\r\n    | n < 10    = [n]\r\n    | otherwise = (n `rem` 10) : digitosR' (n `div` 10)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 4.2. Definir, por comprensi\u00f3n, la funci\u00f3n\r\n--    digitosC :: Integer -> [Integer]\r\n-- tal que (digitosC n) es la lista de los d\u00edgitos del n\u00famero n. Por\r\n-- ejemplo, \r\n--    digitosC 320274  ==  [3,2,0,2,7,4]\r\n-- Indicaci\u00f3n: Usar las funciones show y read.\r\n-- ---------------------------------------------------------------------\r\n\r\ndigitosC :: Integer -> [Integer]\r\ndigitosC n = [read [x] | x <- show n]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 4.3. Comprobar con QuickCheck que las funciones digitosR y\r\n-- digitosC son equivalentes.\r\n-- ---------------------------------------------------------------------\r\n\r\n-- La propiedad es\r\nprop_digitos n =\r\n    n >= 0 ==> \r\n    digitosR n == digitosC n\r\n  \r\n-- La comprobaci\u00f3n es\r\n--    *Main> quickCheck prop_digitos\r\n--    +++ OK, passed 100 tests.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 5.1. Definir, por recursi\u00f3n, la funci\u00f3n \r\n--    sumaDigitosR :: Integer -> Integer\r\n-- tal que (sumaDigitosR n) es la suma de los d\u00edgitos de n. Por ejemplo,\r\n--    sumaDigitosR 3     ==  3\r\n--    sumaDigitosR 2454  == 15\r\n--    sumaDigitosR 20045 == 11\r\n-- ---------------------------------------------------------------------\r\n\r\nsumaDigitosR :: Integer -> Integer\r\nsumaDigitosR n\r\n    | n < 10    = n\r\n    | otherwise = n `rem` 10 + sumaDigitosR (n `div` 10)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 5.2. Definir, sin usar recursi\u00f3n, la funci\u00f3n \r\n--    sumaDigitosNR :: Integer -> Integer\r\n-- tal que (sumaDigitosNR n) es la suma de los d\u00edgitos de n. Por ejemplo,\r\n--    sumaDigitosNR 3     ==  3\r\n--    sumaDigitosNR 2454  == 15\r\n--    sumaDigitosNR 20045 == 11\r\n-- ---------------------------------------------------------------------\r\n\r\nsumaDigitosNR :: Integer -> Integer\r\nsumaDigitosNR n = sum (digitosC n)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 5.3. Comprobar con QuickCheck que las funciones sumaDigitosR\r\n-- y sumaDigitosNR son equivalentes.\r\n-- ---------------------------------------------------------------------\r\n\r\n-- La propiedad es\r\nprop_sumaDigitos n =\r\n    n >= 0 ==>\r\n    sumaDigitosR n == sumaDigitosNR n\r\n\r\n-- La comprobaci\u00f3n es\r\n--    *Main> quickCheck prop_sumaDigitos\r\n--    +++ OK, passed 100 tests.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 6. Definir la funci\u00f3n \r\n--    esDigito :: Integer -> Integer -> Bool\r\n-- tal que (esDigito x n) se verifica si x es un d\u00edgito de n. Por\r\n-- ejemplo, \r\n--    esDigito 4 1041  ==  True\r\n--    esDigito 3 1041  ==  False\r\n-- ---------------------------------------------------------------------\r\n\r\nesDigito :: Integer -> Integer -> Bool\r\nesDigito x n = x `elem` digitosC n\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 7. Definir la funci\u00f3n\r\n--    numeroDeDigitos :: Integer -> Integer\r\n-- tal que (numeroDeDigitos x) es el n\u00famero de d\u00edgitos de x. Por ejemplo,\r\n--    numeroDeDigitos 34047  ==  5\r\n-- ---------------------------------------------------------------------\r\n\r\nnumeroDeDigitos :: Integer -> Int\r\nnumeroDeDigitos x = length (digitosC x)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 8.1 Definir, por recursi\u00f3n, la funci\u00f3n \r\n--    listaNumeroR :: [Integer] -> Integer\r\n-- tal que (listaNumeroR xs) es el n\u00famero formado por los d\u00edgitos xs. Por\r\n-- ejemplo, \r\n--    listaNumeroR [5]        == 5\r\n--    listaNumeroR [1,3,4,7]  == 1347\r\n--    listaNumeroR [0,0,1]    == 1\r\n-- ---------------------------------------------------------------------\r\n\r\nlistaNumeroR :: [Integer] -> Integer\r\nlistaNumeroR xs = listaNumeroR' (reverse xs)\r\n\r\nlistaNumeroR' :: [Integer] -> Integer\r\nlistaNumeroR' [x]    = x\r\nlistaNumeroR' (x:xs) = x + 10 * (listaNumeroR' xs)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 8.2. Definir, por comprensi\u00f3n, la funci\u00f3n \r\n--    listaNumeroC :: [Integer] -> Integer\r\n-- tal que (listaNumeroC xs) es el n\u00famero formado por los d\u00edgitos xs. Por\r\n-- ejemplo, \r\n--    listaNumeroC [5]        == 5\r\n--    listaNumeroC [1,3,4,7]  == 1347\r\n--    listaNumeroC [0,0,1]    == 1\r\n-- ---------------------------------------------------------------------\r\n\r\nlistaNumeroC :: [Integer] -> Integer\r\nlistaNumeroC xs = sum [y*10^n | (y,n) <- zip (reverse xs) [0..]]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 9.1. Definir, por recursi\u00f3n, la funci\u00f3n \r\n--    pegaNumerosR :: Integer -> Integer -> Integer\r\n-- tal que (pegaNumerosR x y) es el n\u00famero resultante de \"pegar\" los\r\n-- n\u00fameros x e y. Por ejemplo, \r\n--    pegaNumerosR 12 987   ==  12987\r\n--    pegaNumerosR 1204 7   ==  12047\r\n--    pegaNumerosR 100 100  ==  100100\r\n-- ---------------------------------------------------------------------\r\n\r\npegaNumerosR :: Integer -> Integer -> Integer\r\npegaNumerosR x y\r\n    | y < 10    = 10*x+y\r\n    | otherwise = 10 * pegaNumerosR x (y `div`10) + (y `mod` 10)  \r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 9.2. Definir, sin usar recursi\u00f3n, la funci\u00f3n \r\n--    pegaNumerosNR :: Integer -> Integer -> Integer\r\n-- tal que (pegaNumerosNR x y) es el n\u00famero resultante de \"pegar\" los\r\n-- n\u00fameros x e y. Por ejemplo, \r\n--    pegaNumerosNR 12 987   ==  12987\r\n--    pegaNumerosNR 1204 7   ==  12047\r\n--    pegaNumerosNR 100 100  ==  100100\r\n-- ---------------------------------------------------------------------\r\n\r\npegaNumerosNR :: Integer -> Integer -> Integer\r\npegaNumerosNR x y = listaNumeroC (digitosC x ++ digitosC y)\r\n\r\n-- Otra definici\u00f3n es\r\npegaNumerosNR2 :: Integer -> Integer -> Integer\r\npegaNumerosNR2 x y = (x * (10^(numeroDeDigitos y))) + y\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 9.3. Comprobar con QuickCheck que las funciones\r\n-- pegaNumerosR y pegaNumerosNR son equivalentes.\r\n-- ---------------------------------------------------------------------\r\n\r\n-- La propiedad es\r\nprop_pegaNumeros x y =\r\n    x >= 0 && y >= 0 ==>\r\n    pegaNumerosR x y == pegaNumerosNR x y\r\n\r\n-- La comprobci\u00f3n es\r\n--    *Main> quickCheck prop_pegaNumeros\r\n--    +++ OK, passed 100 tests.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 10.1. Definir, por recursi\u00f3n, la funci\u00f3n \r\n--    primerDigitoR :: Integer -> Integer\r\n-- tal que (primerDigitoR n) es el primer d\u00edgito de n. Por ejemplo, \r\n--    primerDigitoR 425  ==  4\r\n-- ---------------------------------------------------------------------\r\n\r\nprimerDigitoR :: Integer -> Integer\r\nprimerDigitoR n \r\n    | n < 10    = n\r\n    | otherwise = primerDigitoR (n `div` 10)\r\n  \r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 10.2. Definir, sin usar recursi\u00f3n, la funci\u00f3n \r\n--    primerDigitoNR :: Integer -> Integer\r\n-- tal que (primerDigitoNR n) es la primera digito de n. Por ejemplo, \r\n--    primerDigitoNR 425  ==  4\r\n-- ---------------------------------------------------------------------\r\n\r\nprimerDigitoNR :: Integer -> Integer\r\nprimerDigitoNR n = head (digitosC n)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 10.3. Comprobar con QuickCheck que las funciones\r\n-- primerDigitoR y primerDigitoNR son equivalentes.\r\n-- ---------------------------------------------------------------------\r\n\r\n-- La propiedad es\r\nprop_primerDigito x =\r\n    x >= 0 ==>\r\n    primerDigitoR x == primerDigitoNR x\r\n\r\n-- La comprobaci\u00f3n es\r\n--    *Main> quickCheck prop_primerDigito\r\n--    +++ OK, passed 100 tests.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 11. Definir la funci\u00f3n \r\n--    ultimoDigito :: Integer -> Integer \r\n-- tal que (ultimoDigito n) es el \u00faltimo d\u00edgito de n. Por ejemplo, \r\n--    ultimoDigito 425  ==  5\r\n-- ---------------------------------------------------------------------\r\n\r\nultimoDigito :: Integer -> Integer \r\nultimoDigito n = n `rem` 10\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 12.1. Definir la funci\u00f3n \r\n--    inverso :: Integer -> Integer\r\n-- tal que (inverso n) es el n\u00famero obtenido escribiendo los d\u00edgitos de n\r\n-- en orden inverso. Por ejemplo, \r\n--    inverso 42578  ==  87524\r\n--    inverso 203    ==    302\r\n-- ---------------------------------------------------------------------\r\n\r\ninverso :: Integer -> Integer\r\ninverso n = listaNumeroC (reverse (digitosC n))\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 12.2. Definir, usando show y read, la funci\u00f3n \r\n--    inverso' :: Integer -> Integer\r\n-- tal que (inverso' n) es el n\u00famero obtenido escribiendo los d\u00edgitos de n\r\n-- en orden inverso'. Por ejemplo, \r\n--    inverso' 42578  ==  87524\r\n--    inverso' 203    ==    302\r\n-- ---------------------------------------------------------------------\r\n\r\ninverso' :: Integer -> Integer\r\ninverso' n = read (reverse (show n))\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 12.3. Comprobar con QuickCheck que las funciones\r\n-- inverso e inverso' son equivalentes.\r\n-- ---------------------------------------------------------------------\r\n\r\n-- La propiedad es\r\nprop_inverso n =\r\n    n >= 0 ==>\r\n    inverso n == inverso' n\r\n\r\n-- La comprobaci\u00f3n es\r\n--    *Main> quickCheck prop_inverso\r\n--    +++ OK, passed 100 tests.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 13. Definir la funci\u00f3n \r\n--    capicua :: Integer -> Bool\r\n-- tal que (capicua n) se verifica si si los d\u00edgitos que n son las mismas\r\n-- de izquierda a derecha que de derecha a izquierda. Por ejemplo,\r\n--    capicua 1234  =  False\r\n--    capicua 1221  =  True\r\n--    capicua 4     =  True\r\n-- ---------------------------------------------------------------------\r\n\r\ncapicua :: Integer -> Bool\r\ncapicua n = n == inverso n\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>En la clase de hoy de Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas hemos comentado las soluciones de los ejercicios 8 a 13 de la 9\u00aa relaci\u00f3n en la que se presentan ejercicios con dos definiciones (una por recursi\u00f3n y otra por comprensi\u00f3n) y la comprobaci\u00f3n de la equivalencia de las dos definiciones con QuickCheck&#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":[1],"tags":[298],"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\/2387"}],"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=2387"}],"version-history":[{"count":3,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/2387\/revisions"}],"predecessor-version":[{"id":2732,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/2387\/revisions\/2732"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=2387"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=2387"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=2387"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}