{"id":6814,"date":"2019-10-30T12:38:50","date_gmt":"2019-10-30T11:38:50","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=6814"},"modified":"2019-11-07T11:09:14","modified_gmt":"2019-11-07T10:09:14","slug":"i1m2019-1o-examen-de-programacion-funcional-con-haskell","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/i1m2019-1o-examen-de-programacion-funcional-con-haskell\/","title":{"rendered":"I1M2019: 1\u00ba examen de programaci\u00f3n funcional con Haskell"},"content":{"rendered":"<p>Hoy se ha realizado el 1\u00ba examen del curso de <a href=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-19\">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-- 1\u00ba examen de evaluaci\u00f3n continua (30 de octubre de 2019)\n-- ---------------------------------------------------------------------\n\nimport Test.QuickCheck\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 1. La distancia de Hamming entre dos listas es el n\u00famero de\n-- posiciones en que los correspondientes elementos son distintos. Por\n-- ejemplo, la distancia de Hamming entre \"roma\" y \"loba\" es 2 (porque\n-- hay 2 posiciones en las que los elementos correspondientes son\n-- distintos: la 1\u00aa y la 3\u00aa). \n--    \n-- Definir la funci\u00f3n\n--    distancia :: Eq a => [a] -> [a] -> Int\n-- tal que (distancia xs ys) es la distancia de Hamming entre xs e\n-- ys. Por ejemplo,\n--    distancia \"romano\" \"comino\"  ==  2\n--    distancia \"romano\" \"camino\"  ==  3\n--    distancia \"roma\"   \"comino\"  ==  2\n--    distancia \"roma\"   \"camino\"  ==  3\n--    distancia \"romano\" \"ron\"     ==  1\n--    distancia \"romano\" \"cama\"    ==  2\n--    distancia \"romano\" \"rama\"    ==  1\n-- ---------------------------------------------------------------------\n\n-- 1\u00aa definici\u00f3n (por comprensi\u00f3n):\ndistancia :: Eq a => [a] -> [a] -> Int\ndistancia xs ys = sum [1 | (x,y) <- zip xs ys, x \/= y] \n\n-- 2\u00aa definici\u00f3n (por recursi\u00f3n):\ndistancia2 :: Eq a => [a] -> [a] -> Int\ndistancia2 [] _ = 0\ndistancia2 _ [] = 0\ndistancia2 (x:xs) (y:ys) | x \/= y    = 1 + distancia2 xs ys\n                         | otherwise = distancia2 xs ys\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 2. Definir la funci\u00f3n\n--    esPotencia :: Integer -> Integer -> Bool\n-- tal que (esPotencia x a) se verifica si x es una potencia de a. Por\n-- ejemplo, \n--    esPotencia 32 2  ==  True\n--    esPotencia 42 2  ==  False\n-- ---------------------------------------------------------------------\n\n-- 1\u00aa definici\u00f3n (por comprensi\u00f3n):\nesPotencia :: Integer -> Integer -> Bool\nesPotencia x a = x `elem` [a^n | n <- [0..x]]\n\n-- 2\u00aa definici\u00f3n (por recursi\u00f3n):\nesPotencia2 :: Integer -> Integer -> Bool\nesPotencia2 x a = aux x a 0\n  where aux x a b | b > x     = False\n                  | otherwise = x == a ^ b || aux x a (b+1)\n\n-- 3\u00aa definici\u00f3n (por recursi\u00f3n):\nesPotencia3 :: Integer -> Integer -> Bool\nesPotencia3 0 _ = False\nesPotencia3 1 a = True\nesPotencia3 _ 1 = False\nesPotencia3 x a = rem x a == 0 && esPotencia3 (div x a) a\n\n-- La propiedad de equivalencia es\nprop_equiv_esPotencia :: Integer -> Integer -> Property\nprop_equiv_esPotencia x a =\n    x > 0 && a > 0 ==> \n    esPotencia2 x a == b &&\n    esPotencia3 x a == b\n    where b = esPotencia x a\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_equiv_esPotencia\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3.1. Definir la funci\u00f3n \n--    sumaListas :: [Int] -> [Int] -> [Int]\n-- tal que (sumaListas xs ys) es la suma de las elementos\n-- correspondientes de las lista xs e ys. Por ejemplo,\n--    sumaListas [2,3,4] [1,2,5]  ==  [3,5,9]\n--    sumaListas [2,3,4] [1,2]    ==  [3,5,4]\n--    sumaListas [2,3]   [1,2,5]  ==  [3,5,5]\n-- ------------------------------------------------------------------------\n\n-- 1\u00aa definici\u00f3n \nsumaListas :: [Int] -> [Int] -> [Int]\nsumaListas [] ys         = ys\nsumaListas xs []         = xs\nsumaListas (x:xs) (y:ys) = x+y : sumaListas xs ys\n\n-- 2\u00aa definici\u00f3n\nsumaListas2 :: [Int] -> [Int] -> [Int]\nsumaListas2 xs ys = [x+y | (x,y) <- zip (xs ++ replicate (k-m) 0)\n                                        (ys ++ replicate (k-n) 0)]\n  where m = length xs\n        n = length ys\n        k = max m n\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3.2. Comprobar con QuickCheck que el n\u00famero de elementos de\n-- (sumaListas xs ys) es el m\u00e1ximo de los n\u00fameros de elementos de xs e ys.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_sumaListas :: [Int] -> [Int] -> Bool\nprop_sumaListas xs ys =\n  length (sumaListas xs ys) == max (length xs) (length ys)\n\n-- La comprobaci\u00f3n es\n--    \u03bb> quickCheck prop_sumaListas\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 4. Un n\u00famero primo equilibrado es un n\u00famero primo que es la\n-- media aritm\u00e9tica de su primo anterior y siguiente. Por ejemplo, 5 es\n-- un primo equilibrado porque es la media de 3 y 7; pero 7 no lo es\n-- porque no es la media de 5 y 11.\n--\n-- Definir la funci\u00f3n \n--    primosEquilibrados :: Int -> [Int]\n-- tal que (primosEquilibrados n) es la lista de los n\u00fameros primos\n-- equilibrados menores o iguales que n. Por ejemplo, \n--    ghci> primosEquilibrados 1000\n--    [5,53,157,173,211,257,263,373,563,593,607,653,733,947,977]\n-- ---------------------------------------------------------------------\n\n-- 1\u00aa soluci\u00f3n\n-- ===========\n\nprimosEquilibrados :: Int -> [Int]\nprimosEquilibrados n =\n  [x | x <- [5,7..n]\n     , esPrimo x\n     , esEquilibrado x]\n\n-- (esPrimo n) se verifica si n es primo. Por ejemplo,\n--    esPrimo 5  ==  True\n--    esPrimo 6  ==  False\nesPrimo :: Int -> Bool\nesPrimo n = divisores n == [1,n]\n\n-- (primos n) es la lista de los n\u00fameros primos menores o iguales que\n-- n. Por ejemplo,\n--    primos 50  ==  [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47]\nprimos :: Int -> [Int]\nprimos n = [x | x <- [1..n], esPrimo x]\n\n-- (divisores n) es la lista de los divisores de n Por ejemplo,\n--    divisores 36  ==  [1,2,3,4,6,9,12,18,36]\ndivisores :: Int -> [Int]\ndivisores n = [x | x <- [1..n], n `mod` x == 0]\n\n-- (esEquilibrado x) se verifica si x es la media de su primo anterior y\n-- su primo siguiente. Por ejemplo,\n--    esEquilibrado 5  ==  True\n--    esEquilibrado 7  ==  False\nesEquilibrado :: Int -> Bool\nesEquilibrado x = 2 * x == primoAnterior x + primoSiguiente x\n\n-- (primoAnterior x) es el primo anterior a x. Por ejemplo,\n--    primoAnterior 22  ==  19\nprimoAnterior :: Int -> Int\nprimoAnterior x = head [y | y <- [x-1,x-2..]\n                          , esPrimo y]\n\n-- (primoSiguiente x) es el primo siguiente a x. Por ejemplo,\n--    primoSiguiente 22  ==  23\n--    primoSiguiente 23  ==  29\nprimoSiguiente :: Int -> Int\nprimoSiguiente x = head [y | y <- [x+1..]\n                           , esPrimo y]\n\n-- 2\u00aa soluci\u00f3n\n-- ===========\n\nprimosEquilibrados2 :: Int -> [Int]\nprimosEquilibrados2 n = aux (primos n)\n  where aux (x1:x2:x3:xs)\n          | 2*x2 == x1+x3 = x2 : aux (x2:x3:xs)\n          | otherwise     = aux (x2:x3:xs)\n        aux _             = []\n        \n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Hoy se ha realizado el 1\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":[331],"tags":[],"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\/6814"}],"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=6814"}],"version-history":[{"count":1,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/6814\/revisions"}],"predecessor-version":[{"id":6815,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/6814\/revisions\/6815"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=6814"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=6814"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=6814"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}