{"id":6410,"date":"2018-12-19T18:18:49","date_gmt":"2018-12-19T17:18:49","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=6410"},"modified":"2018-12-22T08:19:39","modified_gmt":"2018-12-22T07:19:39","slug":"i1m2018-2o-examen-de-programacion-funcional-con-haskell","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/i1m2018-2o-examen-de-programacion-funcional-con-haskell\/","title":{"rendered":"I1M2018: 2\u00ba examen de programaci\u00f3n funcional con Haskell"},"content":{"rendered":"<p>Hoy se ha realizado el 2\u00ba examen del curso de <a href=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-18\">Inform\u00e1tica<\/a> (de 1\u00ba de Grado en Matem\u00e1ticas). Los ejercicios, y sus soluciones, se muestran a continuaci\u00f3n.<\/p>\n<p><!--more--><\/p>\n<pre lang=\"haskell\">\n-- Inform\u00e1tica (1\u00ba del Grado en Matem\u00e1ticas, Grupo 4)\n-- 2\u00ba examen de evaluaci\u00f3n continua (19 de diciembre de 2018)\n-- ---------------------------------------------------------------------\n\n-- Nota: La puntuaci\u00f3n de cada ejercicio es 2.5 puntos.\n\nimport Data.Char \nimport Test.QuickCheck\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 1. Se dice que un n\u00famero natural n es una colina si su\n-- primer d\u00edgito es igual a su \u00faltimo d\u00edgito, los primeros d\u00edgitos son\n-- estrictamente creciente hasta llegar al m\u00e1ximo, el m\u00e1ximo se puede\n-- repetir y los d\u00edgitos desde el m\u00e1ximo al final son estrictamente\n-- decrecientes. \n--\n-- Definir la funci\u00f3n\n--    esColina :: Integer -> Bool\n-- tal que (esColina n) se verifica si n es un n\u00famero colina. Por\n-- ejemplo, \n--    esColina 12377731  ==  True\n--    esColina 1237731   ==  True\n--    esColina 123731    ==  True\n--    esColina 122731    ==  False\n--    esColina 12377730  ==  False\n--    esColina 12374731  ==  False\n--    esColina 12377730  ==  False\n--    esColina 10377731  ==  False\n--    esColina 12377701  ==  False\n--    esColina 33333333  ==  True\n-- ---------------------------------------------------------------------\n\n-- 1\u00aa definici\u00f3n\n-- =============\n\nesColina :: Integer -> Bool\nesColina n =\n  head ds == last ds &&\n  esCreciente xs &&\n  esDecreciente ys\n  where ds = digitos n\n        m  = maximum ds\n        xs = takeWhile (<m) ds\n        ys = dropWhile (==m) (dropWhile (<m) ds)\n\n-- (digitos n) es la lista de los d\u00edgitos de n. Por ejemplo,\n--    digitos 425  ==  [4,2,5]\ndigitos :: Integer -> [Int]\ndigitos n = map digitToInt (show n)\n\n-- (esCreciente xs) se verifica si la lista xs es estrictamente\n-- creciente. Por ejemplo,\n--    esCreciente [2,4,7]  ==  True\n--    esCreciente [2,2,7]  ==  False\n--    esCreciente [2,1,7]  ==  False\nesCreciente :: [Int] -> Bool\nesCreciente xs = and [x < y | (x,y) <- zip xs (tail xs)]\n\n-- (esDecreciente xs) se verifica si la lista xs es estrictamente\n-- decreciente. Por ejemplo,\n--    esDecreciente [7,4,2]  ==  True\n--    esDecreciente [7,2,2]  ==  False\n--    esDecreciente [7,1,2]  ==  False\nesDecreciente :: [Int] -> Bool\nesDecreciente xs = and [x > y | (x,y) <- zip xs (tail xs)]\n\n-- 2\u00aa definici\u00f3n\n-- =============\n\nesColina2 :: Integer -> Bool\nesColina2 n =\n  head ds == last ds &&\n  null (dropWhile (==(-1)) (dropWhile (==0) (dropWhile (==1) xs)))\n  where ds = digitos n\n        xs = [signum (y-x) | (x,y) <- zip ds (tail ds)] \n\n-- Equivalencia\n-- ============\n\n-- La propiedad de equivalencia es\nprop_esColina :: Integer -> Property\nprop_esColina n =\n  n >= 0 ==> esColina n == esColina2 n \n\n-- La comprobaci\u00f3n es\n--    \u03bb> quickCheck prop_esColina\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 2. La persistencia multiplicativa de un n\u00famero  es la\n-- cantidad de pasos requeridos para reducirlo a un d\u00edgito multiplicando\n-- sus d\u00edgitos. Por ejemplo, la persistencia de 39 es 3 porque 3*9 = 27,\n-- 2*7 = 14 y 1*4 = 4.  \n--\n-- Definir la funci\u00f3n\n--    persistencia     :: Integer -> Integer\n-- tal que (persistencia x) es la persistencia de x. Por ejemplo,\n--    persistencia 39                             ==   3\n--    persistencia 2677889                        ==   8\n--    persistencia 26888999                       ==   9\n--    persistencia 3778888999                     ==  10\n--    persistencia 277777788888899                ==  11\n--    persistencia 77777733332222222222222222222  ==  11\n-- ---------------------------------------------------------------------\n\npersistencia :: Integer -> Integer\npersistencia x\n  | x < 10    = 0\n  | otherwise = 1 + persistencia (productoDigitos x)\n\nproductoDigitos :: Integer -> Integer\nproductoDigitos x \n  | x < 10    = x\n  | otherwise = r * productoDigitos y\n  where (y,r) = quotRem x 10\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3. Definir la funci\u00f3n\n--    producto :: [[a]] -> [[a]]\n-- tal que (producto xss) es el producto cartesiano de los conjuntos\n-- xss. Por ejemplo,\n--    ghci> producto [[1,3],[2,5]]\n--    [[1,2],[1,5],[3,2],[3,5]]\n--    ghci> producto [[1,3],[2,5],[6,4]]\n--    [[1,2,6],[1,2,4],[1,5,6],[1,5,4],[3,2,6],[3,2,4],[3,5,6],[3,5,4]]\n--    ghci> producto [[1,3,5],[2,4]]\n--    [[1,2],[1,4],[3,2],[3,4],[5,2],[5,4]]\n--    ghci> producto []\n--    [[]]\n-- ---------------------------------------------------------------------\n\n-- 1\u00aa soluci\u00f3n\nproducto :: [[a]] -> [[a]]\nproducto []       = [[]]\nproducto (xs:xss) = [x:ys | x <- xs, ys <- producto xss]\n\n-- 2\u00aa soluci\u00f3n\nproducto2 :: [[a]] -> [[a]]\nproducto2 = foldr f [[]]\n  where f xs xss = [x:ys | x <- xs, ys <- xss]\n\n-- 3\u00aa soluci\u00f3n\nproducto3 :: [[a]] -> [[a]]\nproducto3 = foldr aux [[]] \n  where aux [] _      = []\naux (x:xs) ys = map (x:) ys ++ aux xs ys\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 4. Las expresiones aritm\u00e9ticas. generales se contruyen con\n-- las sumas generales (sumatorios) y productos generales\n-- (productorios). Su tipo es \n--    data Expresion = N Int\n--                   | S [Expresion]\n--                   | P [Expresion]\n--      deriving Show\n-- Por ejemplo, la expresi\u00f3n (2 * (1 + 2 + 1) * (2 + 3)) + 1 se\n-- representa por S [P [N 2, S [N 1, N 2, N 1], S [N 2, N 3]], N 1]\n--\n-- Definir la funci\u00f3n\n--    valor :: Expresion -> Int\n-- tal que (valor e) es el valor de la expresi\u00f3n e. Por ejemplo,\n--    \u03bb> valor (S [P [N 2, S [N 1, N 2, N 1], S [N 2, N 3]], N 1])\n--    41\n-- ---------------------------------------------------------------------\n\ndata Expresion = N Int\n               | S [Expresion]\n               | P [Expresion]\n  deriving Show\n\nvalor :: Expresion -> Int\nvalor (N x)  = x\nvalor (S es) = sum (map valor es)\nvalor (P es) = product (map valor es)\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Hoy se ha realizado el 2\u00ba examen del curso de Inform\u00e1tica (de 1\u00ba de Grado en Matem\u00e1ticas). Los ejercicios, y sus soluciones, se muestran a continuaci\u00f3n.<\/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":[320],"tags":[270,321],"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\/6410"}],"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=6410"}],"version-history":[{"count":1,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/6410\/revisions"}],"predecessor-version":[{"id":6411,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/6410\/revisions\/6411"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=6410"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=6410"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=6410"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}