{"id":2375,"date":"2012-11-29T19:20:36","date_gmt":"2012-11-29T19:20:36","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=2375"},"modified":"2013-03-08T05:47:37","modified_gmt":"2013-03-08T05:47:37","slug":"i1m2011-ejercicios-de-definiciones-por-recursion-y-comprension-en-haskell-1-2","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/i1m2011-ejercicios-de-definiciones-por-recursion-y-comprension-en-haskell-1-2\/","title":{"rendered":"I1M2011: Ejercicios de definiciones por recursi\u00f3n y comprensi\u00f3n en Haskell (1)"},"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 7 primeros ejercicios 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\nimport Data.List\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 1.1. Definir, por recursi\u00f3n, la funci\u00f3n \r\n--    sumaCuadradosR :: Integer -> Integer\r\n-- tal que (sumaCuadradosR n) es la suma de los cuadrados de los n\u00fameros\r\n-- de 1 a n. Por ejemplo, \r\n--    sumaCuadradosR 4  ==  30 \r\n-- ---------------------------------------------------------------------\r\n\r\nsumaCuadradosR :: Integer -> Integer\r\nsumaCuadradosR 0 = 0\r\nsumaCuadradosR n = n*n + sumaCuadradosR n \r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 1.2. Comprobar con QuickCheck si sumaCuadradosR n es igual a\r\n-- n(n+1)(2n+1)\/6. \r\n-- ---------------------------------------------------------------------\r\n\r\n-- La propiedad es\r\nprop_SumaCuadrados n =\r\n  n >= 0 ==>\r\n    sumaCuadradosR n == n * (n+1) * (2*n+1) `div` 6  \r\n\r\n-- La comprobaci\u00f3n es\r\n--    Main> quickCheck prop_SumaCuadrados\r\n--    OK, passed 100 tests.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 1.3. Definir, por comprensi\u00f3n, la funci\u00f3n \r\n--    sumaCuadradosC :: Integer --> Integer\r\n-- tal que (sumaCuadradosC n) es la suma de los cuadrados de los n\u00fameros\r\n-- de 1 a n. Por ejemplo, \r\n--    sumaCuadradosC 4  ==  30 \r\n-- ---------------------------------------------------------------------\r\n\r\nsumaCuadradosC :: Integer -> Integer\r\nsumaCuadradosC n = sum [x^2 | x <- [1..n]]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 1.4. Comprobar con QuickCheck que las funciones\r\n-- sumaCuadradosR y sumaCuadradosC son equivalentes sobre los n\u00fameros\r\n-- naturales. \r\n-- ---------------------------------------------------------------------\r\n\r\n-- La propiedad es\r\nprop_sumaCuadradosR n =\r\n    n >= 0 ==> sumaCuadradosR n == sumaCuadradosC n\r\n\r\n-- La comprobaci\u00f3n es\r\n--    *Main> quickCheck prop_sumaCuadrados\r\n--    +++ OK, passed 100 tests.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 2.1. Se quiere formar una escalera con bloques cuadrados,\r\n-- de forma que tenga un n\u00famero determinado de escalones. Por ejemplo,\r\n-- una escalera con tres escalones tendr\u00eda la siguiente forma:\r\n--        XX\r\n--      XXXX\r\n--    XXXXXX\r\n-- Definir, por recursi\u00f3n, la funci\u00f3n \r\n--    numeroBloquesR :: Integer -> Integer    \r\n-- tal que (numeroBloquesR n) es el n\u00famero de bloques necesarios para\r\n-- construir una escalera con n escalones. Por ejemplo,\r\n--    numeroBloquesR 1   == 2\r\n--    numeroBloquesR 3   == 12\r\n--    numeroBloquesR 10  == 110\r\n-- ---------------------------------------------------------------------\r\n\r\nnumeroBloquesR :: Integer -> Integer    \r\nnumeroBloquesR 0 = 0\r\nnumeroBloquesR n = 2*n + numeroBloquesR (n-1) \r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 2.2. Definir, por comprensi\u00f3n, la funci\u00f3n \r\n--    numeroBloquesC :: Integer -> Integer    \r\n-- tal que (numeroBloquesC n) es el n\u00famero de bloques necesarios para\r\n-- construir una escalera con n escalones. Por ejemplo,\r\n--    numeroBloquesC 1   == 2\r\n--    numeroBloquesC 3   == 12\r\n--    numeroBloquesC 10  == 110\r\n-- ---------------------------------------------------------------------\r\n\r\nnumeroBloquesC :: Integer -> Integer    \r\nnumeroBloquesC n = sum [2*x | x <- [1..n]]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 2.3. Comprobar con QuickCheck que (numeroBloquesC n) es\r\n-- igual a n+n^2.\r\n-- ---------------------------------------------------------------------\r\n\r\n-- La propiedad es\r\nprop_numeroBloquesR n =\r\n    n >0 ==> numeroBloquesC n == n+n^2\r\n\r\n-- La comprobaci\u00f3n es\r\n--    *Main> quickCheck prop_numeroBloques\r\n--    +++ OK, passed 100 tests.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 3.1. Definir, por recursi\u00f3n, la funci\u00f3n \r\n--    sumaCuadradosImparesR :: Integer -> Integer\r\n-- tal que (sumaCuadradosImparesR n) es la suma de los cuadrados de los\r\n-- n\u00fameros impares desde 1 hasta n. \r\n--    sumaCuadradosImparesR 1  ==  1\r\n--    sumaCuadradosImparesR 7  ==  84\r\n--    sumaCuadradosImparesR 4  ==  10\r\n-- ---------------------------------------------------------------------\r\n\r\nsumaCuadradosImparesR :: Integer -> Integer\r\nsumaCuadradosImparesR 1 = 1\r\nsumaCuadradosImparesR n \r\n    | odd n     = n^2 + sumaCuadradosImparesR (n-1)\r\n    | otherwise = sumaCuadradosImparesR (n-1)\r\n                     \r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 3.2. Definir, por comprensi\u00f3n, la funci\u00f3n \r\n--    sumaCuadradosImparesC :: Integer -> Integer\r\n-- tal que (sumaCuadradosImparesC n) es la suma de los cuadrados de los\r\n-- n\u00fameros impares desde 1 hasta n. \r\n--    sumaCuadradosImparesC 1  ==  1\r\n--    sumaCuadradosImparesC 7  ==  84\r\n--    sumaCuadradosImparesC 4  ==  10\r\n-- ---------------------------------------------------------------------\r\n\r\nsumaCuadradosImparesC :: Integer -> Integer\r\nsumaCuadradosImparesC n = sum [x^2 | x <- [1..n], odd x]\r\n\r\n-- Otra definici\u00f3n m\u00e1s simple es\r\nsumaCuadradosImparesC' :: Integer -> Integer\r\nsumaCuadradosImparesC' n = sum [x^2 | x <- [1,3..n]]\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<\/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 7 primeros ejercicios 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. Los&#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\/2375"}],"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=2375"}],"version-history":[{"count":2,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/2375\/revisions"}],"predecessor-version":[{"id":2734,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/2375\/revisions\/2734"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=2375"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=2375"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=2375"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}