{"id":1715,"date":"2011-11-25T19:53:25","date_gmt":"2011-11-25T19:53:25","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=1715"},"modified":"2013-03-08T05:48:59","modified_gmt":"2013-03-08T05:48:59","slug":"i1m2011-funciones-de-orden-superior-y-ejercicios-de-recursion-y-comprension-en-haskell","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/i1m2011-funciones-de-orden-superior-y-ejercicios-de-recursion-y-comprension-en-haskell\/","title":{"rendered":"I1M2011: Funciones de orden superior y ejercicios de recursi\u00f3n y comprensi\u00f3n en Haskell"},"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> ha tenido dos partes.<\/p>\n<p>En la primera parte hemos visto c\u00f3mo pueden definirse funciones de orden superior en Haskell y su aplicaci\u00f3n para definir las funciones de procesamiento de listas (map y filter). Las transparencias usadas en la clase son las 13 primeras del <a href=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m\/temas\/tema-7t.pdf\">tema 7<\/a><br \/>\n<!--more--><br \/>\n<div class=\"jetpack-video-wrapper\"><iframe src='https:\/\/www.slideshare.net\/slideshow\/embed_code\/6286274' width='1290' height='1057' sandbox=\"allow-popups allow-scripts allow-same-origin allow-presentation\" allowfullscreen webkitallowfullscreen mozallowfullscreen><\/iframe><\/div><\/p>\n<p>En la segunda parte, hemos continuado comentado las soluciones de ejercicios de 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 anterior<\/a>. Los ejercicios, y sus soluciones, se muestran a continuaci\u00f3n:<\/p>\n<pre lang=\"haskell\">\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 8.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 8.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 (cifras x ++ cifras y)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 8.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 9.1. Definir, por recursi\u00f3n, la funci\u00f3n \r\n--    primeraCifraR :: Integer -> Integer\r\n-- tal que (primeraCifraR n) es la primera cifra de n. Por ejemplo, \r\n--    primeraCifraR 425  ==  4\r\n-- ---------------------------------------------------------------------\r\n\r\nprimeraCifraR :: Integer -> Integer\r\nprimeraCifraR n \r\n    | n < 10    = n\r\n    | otherwise = primeraCifraR (n `div` 10)\r\n  \r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 9.2. Definir, sin usar recursi\u00f3n, la funci\u00f3n \r\n--    primeraCifraNR :: Integer -> Integer\r\n-- tal que (primeraCifraNR n) es la primera cifra de n. Por ejemplo, \r\n--    primeraCifraNR 425  ==  4\r\n-- ---------------------------------------------------------------------\r\n\r\nprimeraCifraNR :: Integer -> Integer\r\nprimeraCifraNR n = head (cifras n)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 9.3. Comprobar con QuickCheck que las funciones\r\n-- primeraCifraR y primeraCifraNR son equivalentes.\r\n-- ---------------------------------------------------------------------\r\n\r\n-- La propiedad es\r\nprop_primeraCifra x =\r\n    x >= 0 ==>\r\n    primeraCifraR x == primeraCifraNR x\r\n\r\n-- La comprobaci\u00f3n es\r\n--    *Main> quickCheck prop_primeraCifra\r\n--    +++ OK, passed 100 tests.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 10. Definir la funci\u00f3n \r\n--    ultimaCifra :: Integer -> Integer \r\n-- tal que (ultimaCifra n) es la \u00faltima cifra de n. Por ejemplo, \r\n--    ultimaCifra 425  ==  5\r\n-- ---------------------------------------------------------------------\r\n\r\nultimaCifra :: Integer -> Integer \r\nultimaCifra n = n `rem` 10\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 11.1. Definir la funci\u00f3n \r\n--    inverso :: Integer -> Integer\r\n-- tal que (inverso n) es el n\u00famero obtenido escribiendo las cifras 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 (cifras n))\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 11.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 las cifras 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 11.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 12. Definir la funci\u00f3n \r\n--    capicua :: Integer -> Bool\r\n-- tal que (capicua n) se verifica si si las cifras 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\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 13.1. Definir, por recursi\u00f3n, la funci\u00f3n \r\n--    mayorExponenteR :: Integer -> Integer -> Integer \r\n-- tal que (mayorExponenteR a b) es el exponente de la mayor potencia de\r\n-- a que divide b. Por ejemplo,\r\n--    mayorExponenteR 2 8    ==  3\r\n--    mayorExponenteR 2 9    ==  0\r\n--    mayorExponenteR 5 100  ==  2\r\n--    mayorExponenteR 2 60   ==  2\r\n-- ---------------------------------------------------------------------\r\n\r\nmayorExponenteR :: Integer -> Integer -> Integer \r\nmayorExponenteR a b\r\n    | mod b a \/= 0 = 0\r\n    | otherwise    = 1 + mayorExponenteR a (b `div` a)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 13.2. Definir, por recursi\u00f3n, la funci\u00f3n \r\n--    mayorExponenteC :: Integer -> Integer -> Integer \r\n-- tal que (mayorExponenteC a b) es el exponente de la mayor potencia de\r\n-- a que divide a b. Por ejemplo,\r\n--    mayorExponenteC 2 8    ==  3\r\n--    mayorExponenteC 5 100  ==  2\r\n--    mayorExponenteC 5 101  ==  0\r\n-- ---------------------------------------------------------------------\r\n\r\nmayorExponenteC :: Integer -> Integer -> Integer\r\nmayorExponenteC a b = head [x-1 | x <- [0..], mod b (a^x) \/= 0]\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>La clase de hoy de Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas ha tenido dos partes. En la primera parte hemos visto c\u00f3mo pueden definirse funciones de orden superior en Haskell y su aplicaci\u00f3n para definir las funciones de procesamiento de listas (map y filter). Las transparencias usadas en la clase son las 13 primeras&#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],"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\/1715"}],"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=1715"}],"version-history":[{"count":4,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/1715\/revisions"}],"predecessor-version":[{"id":2901,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/1715\/revisions\/2901"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=1715"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=1715"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=1715"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}