{"id":1635,"date":"2011-10-25T18:50:36","date_gmt":"2011-10-25T18:50:36","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=1635"},"modified":"2013-03-08T05:49:02","modified_gmt":"2013-03-08T05:49:02","slug":"i1m2011-ejercicios-de-definiciones-por-comprension-en-haskell-1","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/i1m2011-ejercicios-de-definiciones-por-comprension-en-haskell-1\/","title":{"rendered":"I1M2011: Ejercicios de definiciones por comprensi\u00f3n en Haskell (1)"},"content":{"rendered":"<p>En 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> hemos comentado las soluciones a los ejercicios de la <a href=\"https:\/\/www.glc.us.es\/~jalonso\/ejerciciosI1M2011G1\/images\/0\/0a\/Rel_2.hs\">3\u00aa relaci\u00f3n<\/a> que trata sobre definiciones por comprensi\u00f3n.<\/p>\n<p>Los ejercicios, y sus soluciones, se muestran a continuaci\u00f3n<br \/>\n<!--more--><\/p>\n<pre lang=\"haskell\">\r\n-- I1M 2011-12: Rel_3_sol.hs (21 de Octubre de 2011)\r\n-- Definiciones por comprensi\u00f3n (1)\r\n-- Departamento de Ciencias de la Computaci\u00f3n e I.A.\r\n-- Universidad de Sevilla\r\n-- =====================================================================\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Introducci\u00f3n                                                       --\r\n-- ---------------------------------------------------------------------\r\n\r\n-- En esta relaci\u00f3n se presentan ejercicios con definiciones por\r\n-- comprensi\u00f3n correspondientes al tema 5 cuyas transparencias se \r\n-- encuentran en  \r\n--    http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-11\/temas\/tema-5.pdf\r\n-- En concreto, se estudian funciones para calcular\r\n-- * la suma de los cuadrados de los n primeros n\u00fameros, \r\n-- * listas con un elemento replicado,\r\n-- * ternas pitag\u00f3ricas, \r\n-- * n\u00fameros perfectos, \r\n-- * producto cartesiano,\r\n-- * posiciones de un elemento en una lista, \r\n-- * producto escalar y \r\n-- * la soluci\u00f3n del problema 1 del proyecto Euler.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 1. Definir, por comprensi\u00f3n, la funci\u00f3n\r\n--    sumaDeCuadrados :: Integer -> Integer\r\n-- tal que (sumaDeCuadrados n) es la suma de los cuadrados de los\r\n-- primeros n n\u00fameros; es decir, 1^2 + 2^2 + ... + n^2. Por ejemplo,\r\n--    sumaDeCuadrados 3    ==  14\r\n--    sumaDeCuadrados 100  ==  338350\r\n-- ---------------------------------------------------------------------\r\n\r\nsumaDeCuadrados :: Integer -> Integer\r\nsumaDeCuadrados n = sum [x^2 | x <- [1..n]]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 2. Definir por comprensi\u00f3n la funci\u00f3n\r\n--    replica :: Int -> a -> [a]\r\n-- tal que (replica n x) es la lista formada por n copias del elemento\r\n-- x. Por ejemplo, \r\n--    replica 3 True  ==  [True, True, True]\r\n-- Nota: La funci\u00f3n replica es equivalente a la predefinida replicate.\r\n-- ---------------------------------------------------------------------\r\n\r\nreplica :: Int -> a -> [a]\r\nreplica n x = [x | _ <- [1..n]]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 3.1. Una terna (x,y,z) de enteros positivos es pitag\u00f3rica\r\n-- si x^2 + y^2 = z^2. Usando una lista por comprensi\u00f3n, definir la\r\n-- funci\u00f3n \r\n--    pitagoricas :: Int -> [(Int,Int,Int)]\r\n-- tal que (pitagoricas n) es la lista de todas las ternas pitag\u00f3ricas\r\n-- cuyas componentes est\u00e1n entre 1 y n. Por ejemplo, \r\n--    pitagoricas 10  ==  [(3,4,5),(4,3,5),(6,8,10),(8,6,10)]\r\n-- ---------------------------------------------------------------------\r\n\r\npitagoricas :: Int -> [(Int,Int,Int)]\r\npitagoricas n = [(x,y,z) | x <- [1..n],\r\n                           y <- [1..n],\r\n                           z <- [1..n],\r\n                           x^2 + y^2 == z^2]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 3.2. Definir la funci\u00f3n \r\n--    numeroDePares :: (Int,Int,Int) -> Int\r\n-- tal que (numeroDePares t) es el n\u00famero de elementos pares de la terna\r\n-- t. Por ejemplo,\r\n--    numeroDePares (3,5,7)  ==  0\r\n--    numeroDePares (3,6,7)  ==  1\r\n--    numeroDePares (3,6,4)  ==  2\r\n--    numeroDePares (4,6,4)  ==  3\r\n-- ---------------------------------------------------------------------\r\n\r\nnumeroDePares :: (Int,Int,Int) -> Int\r\nnumeroDePares (x,y,z) = sum [1 | n <- [x,y,z], even n]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 3.3. Definir la funci\u00f3n\r\n--    conjetura :: Int -> Bool\r\n-- tal que (conjetura n) se verifica si todas las ternas pitag\u00f3ricas\r\n-- cuyas componentes est\u00e1n entre 1 y n tiene un n\u00famero impar de n\u00fameros\r\n-- pares. Por ejemplo,\r\n--    conjetura 10  ==  True\r\n-- ---------------------------------------------------------------------\r\n\r\nconjetura :: Int -> Bool\r\nconjetura n = and [odd (numeroDePares t) | t <- pitagoricas n]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 3.4. Demostrar la conjetura para todas las ternas\r\n-- pitag\u00f3ricas. \r\n-- ---------------------------------------------------------------------\r\n\r\n-- Sea (x,y,z) una terna pitag\u00f3rica. Entonces x^2+y^2=z^2. Pueden darse\r\n-- 4 casos:\r\n-- \r\n-- Caso 1: x e y son pares. Entonces, x^2, y^2 y z^2 tambi\u00e9n lo\r\n-- son. Luego el n\u00famero de componentes pares es 3 que es impar.\r\n-- \r\n-- Caso 2: x es par e y es impar. Entonces, x^2 es par, y^2 es impar y\r\n-- z^2 es impar. Luego el n\u00famero de componentes pares es 1 que es impar.\r\n-- \r\n-- Caso 3: x es impar e y es par. An\u00e1logo al caso 2.\r\n-- \r\n-- Caso 4: x e y son impares. Entonces, x^2 e y^2 tambi\u00e9n son impares y\r\n-- z^2 es par. Luego el n\u00famero de componentes pares es 1 que es impar.\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 4. Un entero positivo es perfecto si es igual a la suma de\r\n-- sus factores, excluyendo el propio n\u00famero. \r\n-- \r\n-- Definir por comprensi\u00f3n la funci\u00f3n \r\n--    perfectos :: Int -> [Int]\r\n-- tal que (perfectos n) es la lista de todos los n\u00fameros perfectos\r\n-- menores que n. Por ejemplo, \r\n--    perfectos 500  ==  [6,28,496]\r\n-- Indicaci\u00f3n: Usar la funci\u00f3n factores del tema 5.\r\n-- ---------------------------------------------------------------------\r\n\r\n-- La funci\u00f3n factores del tema es\r\nfactores :: Int -> [Int]\r\nfactores n = [x | x <- [1..n], n `mod` x == 0]\r\n\r\n-- La definici\u00f3n es\r\nperfectos :: Int -> [Int]\r\nperfectos n = [x | x <- [1..n], sum (init (factores x)) == x]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 5. La funci\u00f3n \r\n--    pares :: [a] -> [b] -> [(a,b)]\r\n-- definida por\r\n--    pares xs ys = [(x,y) | x <- xs, y <- ys]\r\n-- toma como argumento dos listas y devuelve la listas de los pares con\r\n-- el primer elemento de la primera lista y el segundo de la\r\n-- segunda. Por ejemplo,\r\n--    ghci> pares [1..3] [4..6]\r\n--    [(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)]\r\n-- \r\n-- Definir, usando dos listas por comprensi\u00f3n con un generador cada una,\r\n-- la funci\u00f3n \r\n--    pares' :: [a] -> [b] -> [(a,b)]\r\n-- tal que pares' sea equivalente a pares.\r\n-- \r\n-- Indicaci\u00f3n: Utilizar la funci\u00f3n predefinida concat y encajar una\r\n-- lista por comprensi\u00f3n dentro de la otra. \r\n-- ---------------------------------------------------------------------\r\n\r\n-- La definici\u00f3n de pares es\r\npares :: [a] -> [b] -> [(a,b)]\r\npares xs ys = [(x,y) | x <- xs, y <- ys]\r\n\r\n-- La redefinici\u00f3n de pares es\r\npares' :: [a] -> [b] -> [(a,b)]\r\npares' xs ys = concat [[(x,y) | y <- ys] | x <- xs]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 6. En el tema se ha definido la funci\u00f3n \r\n--    posiciones :: Eq a => a -> [a] -> [Int]\r\n-- tal que (posiciones x xs) es la lista de las posiciones ocupadas por\r\n-- el elemento x en la lista xs. Por ejemplo,\r\n--    posiciones 5 [1,5,3,5,5,7]  ==  [1,3,4]\r\n-- \r\n-- Definir, usando la funci\u00f3n busca (definida en el tema 5), la funci\u00f3n\r\n--    posiciones' :: Eq a => a -> [a] -> [Int]\r\n-- tl que posiciones' sea equivalente a posiciones.\r\n-- ---------------------------------------------------------------------\r\n\r\n-- La definici\u00f3n de posiciones es\r\nposiciones :: Eq a => a -> [a] -> [Int]\r\nposiciones x xs = \r\n    [i | (x',i) <- zip xs [0..n], x == x']\r\n    where n = length xs - 1\r\n\r\n-- La definici\u00f3n de busca es\r\nbusca :: Eq a => a -> [(a, b)] -> [b]\r\nbusca c t = [v | (c', v) <- t, c' == c]\r\n\r\n-- La redefinici\u00f3n de posiciones es\r\nposiciones' :: Eq a => a -> [a] -> [Int]\r\nposiciones' x xs = busca x (zip xs [0..])\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 7. El producto escalar de dos listas de enteros xs y ys de\r\n-- longitud n viene dado por la suma de los productos de los elementos\r\n-- correspondientes. \r\n-- \r\n-- Definir por comprensi\u00f3n la funci\u00f3n \r\n--    productoEscalar :: [Int] -> [Int] -> Int\r\n-- tal que (productoEscalar xs ys) es el producto escalar de las listas\r\n-- xs e ys. Por ejemplo,\r\n--    productoEscalar [1,2,3] [4,5,6]  ==  32\r\n-- ---------------------------------------------------------------------\r\n\r\nproductoEscalar :: [Int] -> [Int] -> Int\r\nproductoEscalar xs ys = sum [x*y | (x,y) <- zip xs ys]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 8 (Problema 1 del proyecto Euler) Definir la funci\u00f3n\r\n--    euler1 :: Integer -> Integer\r\n-- (euler1 n) es la suma de todos los m\u00faltiplos de 3 \u00f3 5 menores que\r\n-- n. Por ejemplo,\r\n--    euler1 10  ==  23\r\n-- \r\n-- Calcular la suma de todos los m\u00faltiplos de 3 \u00f3 5 menores que 1000.\r\n-- ---------------------------------------------------------------------\r\n\r\neuler1 :: Integer -> Integer\r\neuler1 n = sum [x | x <- [1..n-1], multiplo x 3 || multiplo x 5]\r\n    where multiplo x y = mod x y == 0\r\n\r\n-- C\u00e1lculo:\r\n--    ghci> euler1 1000\r\n--    233168\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>En la clase de hoy de Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas hemos comentado las soluciones a los ejercicios de la 3\u00aa relaci\u00f3n que trata sobre definiciones por comprensi\u00f3n. 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":[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\/1635"}],"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=1635"}],"version-history":[{"count":3,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/1635\/revisions"}],"predecessor-version":[{"id":2928,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/1635\/revisions\/2928"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=1635"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=1635"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=1635"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}