{"id":4561,"date":"2014-11-05T16:43:56","date_gmt":"2014-11-05T15:43:56","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=4561"},"modified":"2014-11-11T16:44:57","modified_gmt":"2014-11-11T15:44:57","slug":"i1m2014-1o-examen-de-programacion-con-haskell","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/i1m2014-1o-examen-de-programacion-con-haskell\/","title":{"rendered":"I1M2014: 1\u00ba examen de programaci\u00f3n 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-14\">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)\n-- 1\u00ba examen de evaluaci\u00f3n continua (5 de noviembre de 2014)\n-- ---------------------------------------------------------------------\n\nimport Data.Char\nimport Test.QuickCheck\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 1.1. 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 1.2. Comprobar con QuickCheck que, para cualesquiera n\u00fameros\n-- enteros positivos x y a, x es potencia de a si y s\u00f3lo si x\u00b2 es\n-- potencia de a\u00b2. \n-- ---------------------------------------------------------------------\n\n-- Propiedad de potencia\nprop_potencia :: Integer -> Integer -> Property\nprop_potencia x a =\n    x > 0 && a > 0 ==> esPotencia x a == esPotencia (x*x) (a*a)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 2.1. Definir la funci\u00f3n \n--    intercambia :: String -> String\n-- tal que (intercambia xs) es la cadena obtenida poniendo la may\u00fasculas\n-- de xs en min\u00fascula y las min\u00fasculas en may\u00fascula. Por ejemplo,\n--    intercambia \"Hoy es 5 de Noviembre\"  ==  \"hOY ES 5 DE nOVIEMBRE\"\n--    intercambia \"hOY ES 5 DE nOVIEMBRE\"  ==  \"Hoy es 5 de Noviembre\"\n-- ---------------------------------------------------------------------\n\nintercambia :: String -> String\nintercambia xs = [intercambiaCaracter x | x <- xs]\n\nintercambiaCaracter :: Char -> Char\nintercambiaCaracter c | isLower c = toUpper c\n                      | otherwise = toLower c\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 2.2. Comprobar con QuickCheck que, para cualquier cadena xs\n-- se tiene que (intercambia (intercambia ys)) es igual a ys, siendo ys\n-- la lista de las letras (may\u00fasculas o min\u00fasculas no acentuadas) de xs.\n-- ---------------------------------------------------------------------\n\nprop_intercambia :: String -> Bool\nprop_intercambia xs = intercambia (intercambia ys) == ys\n    where ys = [x | x <- xs, x `elem` ['a'..'z'] ++ ['A'..'Z']]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3.1. Definir la funci\u00f3n\n--    primosEquidistantes :: Integer -> [(Integer,Integer)]\n-- tal que (primosEquidistantes n) es la lista de pares de primos\n-- equidistantes de n y con la primera componente menor que la\n-- segunda. Por ejemplo,\n--    primosEquidistantes 8   ==  [(3,13),(5,11)]\n--    primosEquidistantes 12  ==  [(5,19),(7,17),(11,13)]\n-- ---------------------------------------------------------------------\n\n-- 1\u00aa definici\u00f3n (por comprensi\u00f3n):\nprimosEquidistantes :: Integer -> [(Integer,Integer)]\nprimosEquidistantes n =\n    [(x,n+(n-x)) | x <- [2..n-1], esPrimo x, esPrimo (n+(n-x))]\n\nesPrimo :: Integer -> Bool\nesPrimo n = [x | x <- [1..n], rem n x == 0] == [1,n]\n\n-- 2\u00aa definici\u00f3n (con zip):\nprimosEquidistantes2 :: Integer -> [(Integer,Integer)]\nprimosEquidistantes2 n =\n    reverse [(x,y) | (x,y) <- zip [n-1,n-2..1] [n+1..], esPrimo x, esPrimo y]\n\n-- Propiedad de equivalencia de las definiciones:\nprop_equiv_primosEquidistantes :: Integer -> Property\nprop_equiv_primosEquidistantes n =\n    n > 0 ==> primosEquidistantes n == primosEquidistantes2 n\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_equiv_primosEquidistantes\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3.2. Comprobar con QuickCheck si se cumple la siguiente\n-- propiedad: \"Todo n\u00famero entero positivo mayor que 4 es equidistante\n-- de dos primos\" \n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_suma2Primos :: Integer -> Property\nprop_suma2Primos n =\n    n > 4 ==> primosEquidistantes n \/= []\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_suma2Primos\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 4.1. Definir la funci\u00f3n \n--    triangulo :: [a] -> [(a,a)]\n-- tal que (triangulo xs) es la lista de los pares formados por cada uno\n-- de los elementos de xs junto con sus siguientes en xs. Por ejemplo,\n--    ghci> triangulo [3,2,5,9,7]\n--    [(3,2),(3,5),(3,9),(3,7),\n--           (2,5),(2,9),(2,7),\n--                 (5,9),(5,7),\n--                       (9,7)]\n-- ---------------------------------------------------------------------\n\n-- 1\u00aa soluci\u00f3n\ntriangulo :: [a] -> [(a,a)]\ntriangulo []     = []\ntriangulo (x:xs) = [(x,y) | y <- xs] ++ triangulo xs\n\n-- 2\u00aa soluci\u00f3n\ntriangulo2 :: [a] -> [(a,a)]\ntriangulo2 []     = [] \ntriangulo2 (x:xs) = zip (repeat x) xs ++ triangulo2 xs\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 4.2. Comprobar con QuickCheck que la longitud de \n-- (triangulo xs) es la suma desde 1 hasta n-1, donde n es el n\u00famero de\n-- elementos de xs. \n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_triangulo :: [Int] -> Bool\nprop_triangulo xs =\n    length (triangulo xs) == sum [1..length xs - 1]\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_triangulo\n--    +++ OK, passed 100 tests.\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":"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":[238],"tags":[270,305,126],"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\/4561"}],"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=4561"}],"version-history":[{"count":1,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/4561\/revisions"}],"predecessor-version":[{"id":4562,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/4561\/revisions\/4562"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=4561"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=4561"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=4561"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}