{"id":4160,"date":"2014-02-23T05:00:41","date_gmt":"2014-02-23T04:00:41","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=4160"},"modified":"2014-02-22T17:30:08","modified_gmt":"2014-02-22T16:30:08","slug":"ejercicios-sobre-definiciones-con-unfoldr","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/ejercicios-sobre-definiciones-con-unfoldr\/","title":{"rendered":"Ejercicios sobre definiciones con unfoldr"},"content":{"rendered":"<p>La siguiente relaci\u00f3n de ejercicios (elaborada para <a href=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m\">I1M<\/a>) presenta una colecci\u00f3n de funciones que se pueden definir usando <a href=\"http:\/\/hackage.haskell.org\/package\/base-4.6.0.1\/docs\/Data-List.html#v:unfoldr\">unfoldr<\/a>.<\/p>\n<p><!--more--><\/p>\n<pre lang=\"haskell\">\r\n-- ---------------------------------------------------------------------\r\n-- \u00a7 Librer\u00edas auxiliares                                             --\r\n-- ---------------------------------------------------------------------\r\n\r\nimport Data.List (unfoldr)\r\nimport Test.QuickCheck\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 1. Definir, usando unfoldr, la funci\u00f3n\r\n--    rango :: Int -> Int -> [Int]\r\n-- tal que (rango n m) es la lista de los n\u00fameros entre n y m, ambos\r\n-- inclusive. Por ejemplo,\r\n--    rango 2 9  ==  [2,3,4,5,6,7,8,9]\r\n-- ---------------------------------------------------------------------\r\n\r\nrango :: Int -> Int -> [Int]\r\nrango n m = unfoldr f n\r\n    where f x | x > m     = Nothing\r\n              | otherwise = Just (x,x+1)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 2. Definir, usando unfoldr, la funci\u00f3n\r\n--    grupos 3 [1..11]  ==  [[1,2,3],[4,5,6],[7,8,9],[10,11]]\r\n-- tal que (grupos xs) es la lista obtenida agrupando en listas de\r\n-- longitud n (salvo, posiblemente la \u00faltima que puede tener menos\r\n-- elementos) los elementos de xs. Por ejemplo,\r\n--    grupos 3 [1..10]  ==  [[1,2,3],[4,5,6],[7,8,9],[10]]\r\n-- ---------------------------------------------------------------------\r\n\r\ngrupos :: Int -> [a] -> [[a]]\r\ngrupos n = unfoldr f \r\n    where f [] = Nothing\r\n          f xs = Just (take n xs, drop n xs)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 3. Redefinir, usando unfoldr, la funci\u00f3n map. Por ejemplo,\r\n--    map' (*2) [1..7]  ==  [2,4,6,8,10,12,14]\r\n-- ---------------------------------------------------------------------\r\n\r\nmap' :: (a -> b) -> [a] -> [b]\r\nmap' f = unfoldr g\r\n    where g []     = Nothing\r\n          g (x:xs) = Just (f x, xs)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 4. Definir, usando unfoldr, la funci\u00f3n\r\n--    enBase :: Int -> Int -> [Int]\r\n-- tal que (enBase b n) es la lista de los d\u00edgitos de n en base b (en\r\n-- orden inverso). Por ejemplo,\r\n--    enBase 2 13  ==  [1,0,1,1]\r\n--    enBase 3 13  ==  [1,1,1]\r\n-- ---------------------------------------------------------------------\r\n\r\nenBase :: Int -> Int -> [Int]\r\nenBase b n = unfoldr f n\r\n    where f 0 = Nothing\r\n          f x = Just (x `rem` b, x `div` b)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 5. Definir, usando unfoldr, la funci\u00f3n\r\n--    diagonal :: [[a]] -> [a]\r\n-- tal que (diagonal xss) es la diagonal principal de la matriz xss. Por\r\n-- ejemplo, \r\n--    diagonal [[1,3,2,7],[4,6,5,9],[2,5,0,3,7]]  ==  [1,6,0]\r\n-- ---------------------------------------------------------------------\r\n\r\ndiagonal :: [[a]] -> [a]\r\ndiagonal xss = unfoldr f xss \r\n    where f []          = Nothing\r\n          f ((x:_):xss) = Just (x, map tail xss)  \r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 6. Definir, usando unfoldr, la funci\u00f3n\r\n--    traspuesta :: [[a]] -> [[a]]\r\n-- tal que (traspuesta xs) es la traspuesta de la matriz xss. Por\r\n-- ejemplo, \r\n--    traspuesta [[1,3,7],[4,6,9],[2,5,0]]  ==  [[1,4,2],[3,6,5],[7,9,0]]\r\n-- ---------------------------------------------------------------------\r\n\r\ntraspuesta :: [[a]] -> [[a]]\r\ntraspuesta xss = unfoldr f xss\r\n    where f ([]:_) = Nothing\r\n          f xss    = Just (map head xss, map tail xss)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 7. Comprobar con QuickCheck que \r\n--    unfoldr f xs == xs\r\n-- donde f es la funci\u00f3n definida por\r\n--    f []     = Nothing\r\n--    f (x:xs) = Just (x,xs)\r\n-- ---------------------------------------------------------------------\r\n\r\n-- La propiedad es\r\nprop_unfoldr :: [Int] -> Bool\r\nprop_unfoldr xs =\r\n    unfoldr f xs == xs\r\n    where f []     = Nothing\r\n          f (x:xs) = Just (x,xs)\r\n\r\n-- La comprobaci\u00f3n es\r\n--    ghci> quickCheck prop_unfoldr\r\n--    +++ OK, passed 100 tests.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 8. Redefinir, usando unfoldr, la funci\u00f3n iterate. Por\r\n-- ejemplo, \r\n--    take 10 (iterate' (+2) 0)  ==  [0,2,4,6,8,10,12,14,16,18]\r\n-- ---------------------------------------------------------------------\r\n\r\niterate' :: (a -> a) -> a -> [a]\r\niterate' f = unfoldr (\\x -> Just (x, f x)) \r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 9. Redefinir, usando unfoldr, la funci\u00f3n repeat. Por\r\n-- ejemplo, \r\n--    take 5 (repeat' 3)  ==  [3,3,3,3,3]\r\n-- ---------------------------------------------------------------------\r\n\r\nrepeat' :: a -> [a]\r\nrepeat' x = unfoldr (\\y -> Just (y,y)) x \r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 10. Redefinir, usando unfoldr, la funci\u00f3n takeWhile. Por\r\n-- ejemplo, \r\n--    takeWhile' (<7) [2,3,9,4,5]  ==  [2,3]\r\n-- ---------------------------------------------------------------------\r\n\r\ntakeWhile' :: (a -> Bool) -> [a] -> [a]\r\ntakeWhile' p  = unfoldr f \r\n    where f [] = Nothing\r\n          f (x:xs) | p x       = Just (x,xs)\r\n                   | otherwise = Nothing\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 11. Redefinir, usando unfoldr, la funci\u00f3n init. Por\r\n-- ejemplo, \r\n--    init' [3..9]  ==  [3,4,5,6,7,8]\r\n-- ---------------------------------------------------------------------\r\n\r\ninit' :: [a] -> [a]\r\ninit' = unfoldr f\r\n    where f (x:y:zs) = Just(x,y:zs)\r\n          f _        = Nothing\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 12. Redefinir, usando unfoldr, la funci\u00f3n zip. Por\r\n-- ejemplo, \r\n--    zip' [1..5] [6..9]  ==  [(1,6),(2,7),(3,8),(4,9)]\r\n--    zip' [1..4] [5..9]  ==  [(1,5),(2,6),(3,7),(4,8)]\r\n-- ---------------------------------------------------------------------\r\n\r\nzip' :: [a] -> [b] -> [(a, b)]\r\nzip' xs ys = unfoldr f (xs,ys)\r\n    where f (x:xs,y:ys) = Just ((x,y),(xs,ys))\r\n          f _           = Nothing\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 13. Redefinir, usando unfoldr, la funci\u00f3n zip. Por\r\n-- ejemplo, \r\n--    zipWith (*) [1..4] [5..9]  ==  [5,12,21,32]\r\n-- ---------------------------------------------------------------------\r\n\r\nzipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]\r\nzipWith' g xs ys = unfoldr f (xs,ys)\r\n    where f (x:xs,y:ys) = Just (g x y,(xs,ys))\r\n          f _           = Nothing\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 14. Definir, con unfoldr, la funci\u00f3n\r\n--    factoriales :: [Integer]\r\n-- tal que factoriales es la lista de los factoriales. Por ejemplo,\r\n--    take 10 factoriales  ==  [1,1,2,6,24,120,720,5040,40320,362880]\r\n-- ---------------------------------------------------------------------\r\n\r\nfactoriales :: [Integer]\r\nfactoriales = 1 : unfoldr f (1,1)\r\n    where f (x,y) = Just (x*y,(x*y,y+1))\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 15. Definir, usando unfoldr, la funci\u00f3n\r\n--    fibs :: [Integer]\r\n-- tal que fibs es la sucesi\u00f3n de Fibonacci. Por ejemplo,\r\n--    take 10 fibs  ==  [0,1,1,2,3,5,8,13,21,34]\r\n-- ---------------------------------------------------------------------\r\n\r\nfibs :: [Integer]\r\nfibs = 0 : 1: unfoldr f (0,1)\r\n    where f (a,b) = Just (a+b,(b,b+a))\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 16. El tri\u00e1ngulo de Pascal es un tri\u00e1ngulo de n\u00fameros\r\n--          1\r\n--         1 1\r\n--        1 2 1\r\n--      1  3 3  1\r\n--     1 4  6  4 1\r\n--    1 5 10 10 5 1\r\n--   ...............\r\n-- construido de la siguiente forma\r\n-- * la primera fila est\u00e1 formada por el n\u00famero 1;\r\n-- * las filas siguientes se construyen sumando los n\u00fameros adyacentes\r\n--   de la fila superior y a\u00f1adiendo un 1 al principio y al final de la\r\n--   fila. \r\n-- \r\n-- Definir, usando unfoldr, la funci\u00f3n\r\n--    pascal :: [[Integer]]\r\n-- tal que pascal es la lista de las l\u00edneas del tri\u00e1ngulo de Pascal. Por\r\n-- ejemplo, \r\n--    ghci> take 6 pascal\r\n--    [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1],[1,5,10,10,5,1]]\r\n-- ---------------------------------------------------------------------\r\n\r\npascal :: [[Integer]]\r\npascal = unfoldr f [1]\r\n    where f xs = Just (xs, zipWith (+) (0:xs) (xs++[0]))\r\n\r\n-- ---------------------------------------------------------------------\r\n-- El tri\u00e1ngulo de Floyd, llamado as\u00ed en honor a Robert Floyd, es un\r\n-- tri\u00e1ngulo rect\u00e1ngulo formado con n\u00fameros naturales. Para crear un\r\n-- tri\u00e1ngulo de Floyd, se comienza con un 1 en la esquina superior\r\n-- izquierda, y se contin\u00faa escribiendo la secuencia de los n\u00fameros\r\n-- naturales de manera que cada l\u00ednea contenga un n\u00famero m\u00e1s que la\r\n-- anterior. Las 5 primeras l\u00edneas del tri\u00e1ngulo de Floyd son\r\n--     1\r\n--     2   3\r\n--     4   5   6\r\n--     7   8   9  10\r\n--    11  12  13  14  15\r\n-- \r\n-- El tri\u00e1ngulo de Floyd tiene varias propiedades matem\u00e1ticas\r\n-- interesantes. Los n\u00fameros del cateto de la parte izquierda forman la\r\n-- secuencia de los n\u00fameros poligonales centrales, mientras que los de\r\n-- la hipotenusa nos dan el conjunto de los n\u00fameros triangulares.\r\n-- \r\n-- Definir, usando unfoldr, la funci\u00f3n        \r\n--    trianguloFloyd :: [[Integer]]\r\n-- tal que trianguloFloyd es el tri\u00e1ngulo de Floyd. Por ejemplo,\r\n--    ghci> take 4 trianguloFloyd\r\n--    [[1],\r\n--     [2,3],\r\n--     [4,5,6],\r\n--     [7,8,9,10]]\r\n-- ---------------------------------------------------------------------\r\n\r\ntrianguloFloyd :: [[Int]]\r\ntrianguloFloyd = unfoldr f [1]\r\n    where f xs = Just (xs,[a..a+n])\r\n                 where a = 1 + last xs\r\n                       n = length xs\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 17. Lo n\u00fameros triangulares se forman como sigue\r\n--    *     *      * \r\n--         * *    * *\r\n--               * * *\r\n--    1     3      6\r\n-- \r\n-- La sucesi\u00f3n de los n\u00fameros triangulares se obtiene sumando los\r\n-- n\u00fameros naturales. As\u00ed, los 5 primeros n\u00fameros triangulares son\r\n--     1 = 1\r\n--     3 = 1+2\r\n--     6 = 1+2+3\r\n--    10 = 1+2+3+4\r\n--    15 = 1+2+3+4+5\r\n-- \r\n-- Definir, usando unfoldr, la funci\u00f3n\r\n--    triangulares :: [Integer]\r\n-- tal que triangulares es la lista de los n\u00fameros triangulares. Por\r\n-- ejemplo, \r\n--    take 10 triangulares  ==  [1,3,6,10,15,21,28,36,45,55]\r\n-- ---------------------------------------------------------------------\r\n\r\ntriangulares :: [Integer]\r\ntriangulares = unfoldr f (0,1)\r\n    where f (x,y) = Just (x+y,(x+y,y+1)) \r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>La siguiente relaci\u00f3n de ejercicios (elaborada para I1M) presenta una colecci\u00f3n de funciones que se pueden definir usando unfoldr.<\/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":[26,221],"tags":[270,279,299],"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\/4160"}],"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=4160"}],"version-history":[{"count":1,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/4160\/revisions"}],"predecessor-version":[{"id":4161,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/4160\/revisions\/4161"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=4160"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=4160"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=4160"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}