{"id":2523,"date":"2013-02-21T18:35:48","date_gmt":"2013-02-21T18:35:48","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=2523"},"modified":"2013-03-08T05:47:34","modified_gmt":"2013-03-08T05:47:34","slug":"i1m2012-ejercicios-de-evaluacion-perezosa-y-listas-infinitas","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/i1m2012-ejercicios-de-evaluacion-perezosa-y-listas-infinitas\/","title":{"rendered":"I1M2012: Ejercicios de evaluaci\u00f3n perezosa y listas infinitas"},"content":{"rendered":"<p>En la clase de hoy de <a href=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-12\">Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas<\/a> hemos comentando las soluciones de los ejercicios de evaluaci\u00f3n perezosa y listas infinitas de las relaciones 16 y 17.<\/p>\n<p>Los ejercicios, y sus soluciones, se muestran a continuaci\u00f3n. Los de la relaci\u00f3n 16 son<br \/>\n<!--more--><\/p>\n<pre lang=\"haskell\">\r\n-- ---------------------------------------------------------------------\r\n-- Importaci\u00f3n de librer\u00edas auxiliares                                  \r\n-- ---------------------------------------------------------------------\r\n\r\nimport Test.QuickCheck\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 1.1. Definir, por recursi\u00f3n, la funci\u00f3n \r\n--    repite :: a -> [a]\r\n-- tal que (repite x) es la lista infinita cuyos elementos son x. Por\r\n-- ejemplo, \r\n--    repite 5           ==  [5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,...\r\n--    take 3 (repite 5)  ==  [5,5,5]\r\n-- Nota: La funci\u00f3n repite es equivalente a la funci\u00f3n repeat definida\r\n-- en el preludio de Haskell.\r\n-- ---------------------------------------------------------------------\r\n\r\nrepite :: a -> [a]\r\nrepite x = x : repite x\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 1.2. Definir, por comprensi\u00f3n, la funci\u00f3n \r\n--    repiteC :: a -> [a]\r\n-- tal que (repiteC x) es la lista infinita cuyos elementos son x. Por\r\n-- ejemplo, \r\n--    repiteC 5           ==  [5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,...\r\n--    take 3 (repiteC 5)  ==  [5,5,5]\r\n-- Nota: La funci\u00f3n repiteC es equivalente a la funci\u00f3n repeat definida\r\n-- en el preludio de Haskell.\r\n-- ---------------------------------------------------------------------\r\n\r\nrepiteC :: a -> [a]\r\nrepiteC x = [x | _ <- [1..]]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 2.1. Definir, por recursi\u00f3n, la funci\u00f3n \r\n--    repiteFinita :: Int-> a -> [a]\r\n-- tal que (repiteFinita n x) es la lista con n elementos iguales a\r\n-- x. Por ejemplo, \r\n--    repiteFinita 3 5  ==  [5,5,5]\r\n-- Nota: La funci\u00f3n repiteFinita es equivalente a la funci\u00f3n replicate\r\n-- definida en el preludio de Haskell.\r\n-- ---------------------------------------------------------------------\r\n\r\nrepiteFinita :: Int -> a -> [a]\r\nrepiteFinita 0 x = []\r\nrepiteFinita n x = x : repiteFinita (n-1) x\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 2.2. Definir, por comprensi\u00f3n, la funci\u00f3n \r\n--    repiteFinitaC :: Int-> a -> [a]\r\n-- tal que (repiteFinitaC n x) es la lista con n elementos iguales a\r\n-- x. Por ejemplo, \r\n--    repiteFinitaC 3 5  ==  [5,5,5]\r\n-- Nota: La funci\u00f3n repiteFinitaC es equivalente a la funci\u00f3n replicate\r\n-- definida en el preludio de Haskell.\r\n-- ---------------------------------------------------------------------\r\n\r\nrepiteFinitaC :: Int -> a -> [a]\r\nrepiteFinitaC n x = [x | _ <- [1..n]]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 2.3. Definir, usando repite, la funci\u00f3n \r\n--    repiteFinita' :: Int-> a -> [a]\r\n-- tal que (repiteFinita' n x) es la lista con n elementos iguales a\r\n-- x. Por ejemplo, \r\n--    repiteFinita' 3 5  ==  [5,5,5]\r\n-- Nota: La funci\u00f3n repiteFinita' es equivalente a la funci\u00f3n replicate\r\n-- definida en el preludio de Haskell.\r\n-- ---------------------------------------------------------------------\r\n\r\nrepiteFinita' :: Int -> a -> [a]\r\nrepiteFinita' n x = take n (repite x)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 3.1. Definir, por comprensi\u00f3n, la funci\u00f3n\r\n--    ecoC :: String -> String\r\n-- tal que (ecoC xs) es la cadena obtenida a partir de la cadena xs\r\n-- repitiendo cada elemento tantas veces como indica su posici\u00f3n: el\r\n-- primer elemento se repite 1 vez, el segundo 2 veces y as\u00ed\r\n-- sucesivamente. Por ejemplo, \r\n--    ecoC \"abcd\"  ==  \"abbcccdddd\"\r\n-- ---------------------------------------------------------------------\r\n\r\necoC :: String -> String\r\necoC xs = concat [replicate i x | (i,x) <- zip [1..] xs]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 3.2. Definir, por recursi\u00f3n, la funci\u00f3n\r\n--    ecoR :: String -> String\r\n-- tal que (ecoR xs) es la cadena obtenida a partir de la cadena xs\r\n-- repitiendo cada elemento tantas veces como indica su posici\u00f3n: el\r\n-- primer elemento se repite 1 vez, el segundo 2 veces y as\u00ed\r\n-- sucesivamente. Por ejemplo, \r\n--    ecoR \"abcd\"  ==  \"abbcccdddd\"\r\n-- ---------------------------------------------------------------------\r\n\r\necoR :: String -> String\r\necoR xs = aux 1 xs\r\n    where aux n [] = []\r\n          aux n (x:xs) = replicate n x ++ aux (n+1) xs\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 4. Definir, usando takeWhile y map, la funci\u00f3n\r\n--    potenciasMenores :: Int -> Int -> [Int]\r\n-- tal que (potenciasMenores x y) es la lista de las potencias de x\r\n-- menores que y. Por ejemplo,\r\n--    potenciasMenores 2 1000  ==  [2,4,8,16,32,64,128,256,512]\r\n-- ---------------------------------------------------------------------\r\n\r\npotenciasMenores :: Int -> Int -> [Int]\r\npotenciasMenores x y = takeWhile (<y) (map (x^) [1..])\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 5. (Problema 303 del proyecto Euler) Definir la funci\u00f3n\r\n--    multiplosRestringidos :: Int -> (Int -> Bool) -> [Int]\r\n-- tal que (multiplosRestringidos n x) es la lista de los m\u00faltiplos de n\r\n-- tales que todas sus d\u00edgitos verifican la propiedad p. Por ejemplo, \r\n--    take 4 (multiplosRestringidos 5 (<=3))  ==  [10,20,30,100]\r\n--    take 5 (multiplosRestringidos 3 (<=4))  ==  [3,12,21,24,30]\r\n--    take 5 (multiplosRestringidos 3 even)   ==  [6,24,42,48,60]\r\n-- ---------------------------------------------------------------------\r\n\r\nmultiplosRestringidos :: Int -> (Int -> Bool) -> [Int]\r\nmultiplosRestringidos n p = \r\n    [y | y <- [n,2*n..], all p (digitos y)]\r\n\r\n-- (digitos n) es la lista de las d\u00edgitos de n, Por ejemplo, \r\n--    digitos 327  ==  [3,2,7]\r\ndigitos :: Int -> [Int]\r\ndigitos n = [read [x] | x <- show n]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 5. Definir, por recursi\u00f3n, la funci\u00f3n\r\n--    itera :: (a -> a) -> a -> [a]\r\n-- tal que (itera f x) es la lista cuyo primer elemento es x y los\r\n-- siguientes elementos se calculan aplicando la funci\u00f3n f al elemento\r\n-- anterior. Por ejemplo, \r\n--    ghci> itera (+1) 3\r\n--    [3,4,5,6,7,8,9,10,11,12,{Interrupted!}\r\n--    ghci> itera (*2) 1\r\n--    [1,2,4,8,16,32,64,{Interrupted!}\r\n--    ghci> itera (`div` 10) 1972\r\n--    [1972,197,19,1,0,0,0,0,0,0,{Interrupted!}\r\n-- Nota: La funci\u00f3n repite es equivalente a la funci\u00f3n iterate definida\r\n-- en el preludio de Haskell.\r\n-- ---------------------------------------------------------------------\r\n\r\nitera :: (a -> a) -> a -> [a]\r\nitera f x = x : itera f (f x)\r\n\r\n-- ----------------------------------------------------------------------------\r\n-- Ejercicio 6.1. Definir, por recursi\u00f3n, la funci\u00f3n\r\n--    agrupa :: Int -> [a] -> [[a]]\r\n-- tal que (agrupa n xs) es la lista formada por listas de n elementos\r\n-- conscutivos de la lista xs (salvo posiblemente la \u00faltima que puede\r\n-- tener menos de n elementos). Por ejemplo, \r\n--    ghci> agrupa 2 [3,1,5,8,2,7]\r\n--    [[3,1],[5,8],[2,7]]\r\n--    ghci> agrupa 2 [3,1,5,8,2,7,9] \r\n--    [[3,1],[5,8],[2,7],[9]]\r\n--    ghci> agrupa 5 \"todo necio confunde valor y precio\"\r\n--    [\"todo \",\"necio\",\" conf\",\"unde \",\"valor\",\" y pr\",\"ecio\"]\r\n-- ---------------------------------------------------------------------------- \r\n\r\nagrupa :: Int -> [a] -> [[a]]\r\nagrupa n [] = []\r\nagrupa n xs = take n xs : agrupa n (drop n xs)\r\n\r\n-- ----------------------------------------------------------------------------\r\n-- Ejercicio 6.2. Definir, de manera no recursiva, la funci\u00f3n\r\n--    agrupa' :: Int -> [a] -> [[a]]\r\n-- tal que (agrupa' n xs) es la lista formada por listas de n elementos\r\n-- conscutivos de la lista xs (salvo posiblemente la \u00faltima que puede\r\n-- tener menos de n elementos). Por ejemplo, \r\n--    ghci> agrupa' 2 [3,1,5,8,2,7]\r\n--    [[3,1],[5,8],[2,7]]\r\n--    ghci> agrupa' 2 [3,1,5,8,2,7,9] \r\n--    [[3,1],[5,8],[2,7],[9]]\r\n--    ghci> agrupa' 5 \"todo necio confunde valor y precio\"\r\n--    [\"todo \",\"necio\",\" conf\",\"unde \",\"valor\",\" y pr\",\"ecio\"]\r\n-- ---------------------------------------------------------------------------- \r\n\r\nagrupa' :: Int -> [a] -> [[a]]\r\nagrupa' n = takeWhile (not . null)\r\n          . map (take n)\r\n          . iterate (drop n)\r\n\r\n-- Puede verse su funcionamiento en el siguiente ejemplo,\r\n--    iterate (drop 2) [5..10]  \r\n--    ==> [[5,6,7,8,9,10],[7,8,9,10],[9,10],[],[],...\r\n--    map (take 2) (iterate (drop 2) [5..10])\r\n--    ==> [[5,6],[7,8],[9,10],[],[],[],[],...\r\n--    takeWhile (not . null) (map (take 2) (iterate (drop 2) [5..10]))\r\n--    ==> [[5,6],[7,8],[9,10]]\r\n\r\n-- ----------------------------------------------------------------------------\r\n-- Ejercicio 6.3. Definir, y comprobar, con QuickCheck las dos propiedades\r\n-- que caracterizan a la funci\u00f3n agrupa:\r\n-- * todos los grupos tienen que tener la longitud determinada (salvo el\r\n--   \u00faltimo que puede tener una longitud menor) y\r\n-- * combinando todos los grupos se obtiene la lista inicial.\r\n-- ---------------------------------------------------------------------------- \r\n\r\n-- La primera propiedad es\r\nprop_AgrupaLongitud :: Int -> [Int] -> Property\r\nprop_AgrupaLongitud n xs =\r\n    n > 0 && not (null gs) ==>\r\n      and [length g == n | g <- init gs] &#038;&#038;\r\n      0 < length (last gs) &#038;&#038; length (last gs) <= n\r\n    where gs = agrupa n xs\r\n\r\n-- La comprobaci\u00f3n es\r\n--    ghci> quickCheck prop_AgrupaLongitud\r\n--    OK, passed 100 tests.\r\n\r\n-- La segunda propiedad es\r\nprop_AgrupaCombina :: Int -> [Int] -> Property\r\nprop_AgrupaCombina n xs =\r\n    n > 0 ==> concat (agrupa n xs) == xs \r\n\r\n-- La comprobaci\u00f3n es\r\n--    ghci> quickCheck prop_AgrupaCombina\r\n--    OK, passed 100 tests.\r\n\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 7.1. Sea la siguiente operaci\u00f3n, aplicable a cualquier\r\n-- n\u00famero entero positivo:  \r\n--    * Si el n\u00famero es par, se divide entre 2.\r\n--    * Si el n\u00famero es impar, se multiplica por 3 y se suma 1.\r\n-- Dado un n\u00famero cualquiera, podemos considerar su \u00f3rbita, es decir,\r\n-- las im\u00e1genes sucesivas al iterar la funci\u00f3n. Por ejemplo, la \u00f3rbita\r\n-- de 13 es\r\n--    13, 40, 20, 10, 5, 16, 8, 4, 2, 1, 4, 2, 1,...\r\n-- Si observamos este ejemplo, la \u00f3rbita de 13 es peri\u00f3dica, es decir,\r\n-- se repite indefinidamente a partir de un momento dado). La conjetura\r\n-- de Collatz dice que siempre alcanzaremos el 1 para cualquier n\u00famero\r\n-- con el que comencemos. Ejemplos:  \r\n--    * Empezando en n = 6 se obtiene 6, 3, 10, 5, 16, 8, 4, 2, 1.\r\n--    * Empezando en n = 11 se obtiene: 11, 34, 17, 52, 26, 13, 40, 20,\r\n--      10, 5, 16, 8, 4, 2, 1. \r\n--    * Empezando en n = 27, la sucesi\u00f3n tiene 112 pasos, llegando hasta\r\n--      9232 antes de descender a 1:  27, 82, 41, 124, 62, 31, 94, 47,\r\n--      142, 71, 214, 107, 322, 161, 484, 242, 121, 364, 182, 91, 274,\r\n--      137, 412, 206, 103, 310, 155, 466, 233, 700, 350, 175, 526, 263,\r\n--      790, 395, 1186, 593, 1780, 890, 445, 1336, 668, 334, 167, 502,\r\n--      251, 754, 377, 1132, 566, 283, 850, 425, 1276, 638, 319, 958,\r\n--      479, 1438, 719, 2158, 1079, 3238, 1619, 4858, 2429, 7288, 3644,\r\n--      1822, 911, 2734, 1367, 4102, 2051, 6154, 3077, 9232, 4616, 2308,\r\n--      1154, 577, 1732, 866, 433, 1300, 650, 325, 976, 488, 244, 122,\r\n--      61, 184, 92, 46, 23, 70, 35, 106, 53, 160, 80, 40, 20, 10, 5,\r\n--      16, 8, 4, 2, 1. \r\n-- \r\n-- Definir la funci\u00f3n\r\n--    siguiente :: Integer -> Integer\r\n-- tal que (siguiente n) es el siguiente de n en la sucesi\u00f3n de\r\n-- Collatz. Por ejemplo,\r\n--    siguiente 13  ==  40\r\n--    siguiente 40  ==  20\r\n-- ---------------------------------------------------------------------\r\n\r\nsiguiente n | even n    = n `div` 2\r\n            | otherwise = 3*n+1\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 7.2. Definir, por recursi\u00f3n, la funci\u00f3n \r\n--    collatz :: Integer -> [Integer]\r\n-- tal que (collatz n) es la \u00f3rbita de Collatz de n hasta alcanzar el\r\n-- 1. Por ejemplo,\r\n--    collatz 13  ==  [13,40,20,10,5,16,8,4,2,1]\r\n-- ---------------------------------------------------------------------\r\n\r\ncollatz :: Integer -> [Integer]\r\ncollatz 1 = [1]\r\ncollatz n = n : collatz (siguiente n)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 7.3. Definir, sin recursi\u00f3n, la funci\u00f3n \r\n--    collatz' :: Integer -> [Integer]\r\n-- tal que (collatz' n) es la \u00f3rbita de Collatz d n hasta alcanzar el\r\n-- 1. Por ejemplo,\r\n--    collatz' 13  ==  [13,40,20,10,5,16,8,4,2,1]\r\n-- Indicaci\u00f3n: Usar takeWhile e iterate.\r\n-- ---------------------------------------------------------------------\r\n\r\ncollatz' :: Integer -> [Integer]\r\ncollatz' n = (takeWhile (\/=1) (iterate siguiente n)) ++ [1]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 7.4. Definir la funci\u00f3n\r\n--    menorCollatzMayor :: Int -> Integer\r\n-- tal que (menorCollatzMayor x) es el menor n\u00famero cuya \u00f3rbita de\r\n-- Collatz tiene m\u00e1s de x elementos. Por ejemplo,\r\n--    menorCollatzMayor 100  ==  27\r\n-- ---------------------------------------------------------------------\r\n\r\nmenorCollatzMayor :: Int -> Integer\r\nmenorCollatzMayor x = head [y | y <- [1..], length (collatz y) > x]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 7.5. Definir la funci\u00f3n\r\n--    menorCollatzSupera :: Integer -> Integer\r\n-- tal que (menorCollatzSupera x) es el menor n\u00famero cuya \u00f3rbita de\r\n-- Collatz tiene alg\u00fan elemento mayor que x. Por ejemplo,\r\n--    menorCollatzSupera 100  ==  15\r\n-- ---------------------------------------------------------------------\r\n\r\nmenorCollatzSupera :: Integer -> Integer\r\nmenorCollatzSupera x = \r\n    head [y | y <- [1..], maximum (collatz y) > x]\r\n\r\n-- Otra definici\u00f3n alternativa es\r\nmenorCollatzSupera' :: Integer -> Integer\r\nmenorCollatzSupera' x = head [n | n <- [1..], t <- collatz' n, t > x]\r\n<\/pre>\n<p>y los de la relaci\u00f3n 17 son<\/p>\n<pre lang=\"haskell\">\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 1.1. Definir, usando la criba de Erat\u00f3stenes, la constante\r\n--    primos :: Integral a => [a]\r\n-- cuyo valor es la lista de los n\u00fameros primos. Por ejemplo,\r\n--    take 10 primos  ==  [2,3,5,7,11,13,17,19,23,29]\r\n-- ---------------------------------------------------------------------\r\n\r\nprimos :: Integral a => [a]\r\nprimos = criba [2..]\r\n    where criba []     = []\r\n          criba (n:ns) = n : criba (elimina n ns)\r\n          elimina n xs = [x | x <- xs, x `mod` n \/= 0]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 1.2. Definir la funci\u00f3n\r\n--    primo :: Integral a => a -> Bool\r\n-- tal que (primo n) se verifica si n es primo. Por ejemplo,\r\n--    primo 7  ==  True\r\n--    primo 9  ==  False\r\n-- ---------------------------------------------------------------------\r\n\r\nprimo :: Int -> Bool\r\nprimo n = head (dropWhile (<n) primos) == n\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 6. Definir la funci\u00f3n\r\n--    sumaDeDosPrimos :: Int -> [(Int,Int)]\r\n-- tal que (sumaDeDosPrimos n) es la lista de las distintas\r\n-- descomposiciones de n como suma de dos n\u00fameros primos. Por ejemplo, \r\n--    sumaDeDosPrimos 30  ==  [(7,23),(11,19),(13,17)]\r\n-- Calcular, usando la funci\u00f3n sumaDeDosPrimos, el menor n\u00famero que\r\n-- puede escribirse de 10 formas distintas como suma de dos primos.\r\n-- ---------------------------------------------------------------------\r\n\r\nsumaDeDosPrimos :: Int -> [(Int,Int)]\r\nsumaDeDosPrimos n = \r\n    [(x,n-x) | x <- primosN, x < n-x, elem (n-x) primosN]\r\n    where primosN = takeWhile (<=n) primos\r\n\r\n-- El c\u00e1lculo es\r\n--    ghci> head [x | x <- [1..], length (sumaDeDosPrimos x) == 10]\r\n--    114\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 3. Definir la funci\u00f3n\r\n--    esProductoDeDosPrimos :: Int -> Bool\r\n-- tal que (esProductoDeDosPrimos n) se verifica si n es el producto de\r\n-- dos primos distintos. Por ejemplo,\r\n--    esProductoDeDosPrimos 6  ==  True\r\n--    esProductoDeDosPrimos 9  ==  False\r\n-- ---------------------------------------------------------------------\r\n\r\nesProductoDeDosPrimos :: Int -> Bool\r\nesProductoDeDosPrimos n =\r\n    [x | x <- primosN, \r\n         mod n x == 0, \r\n         div n x \/= x, \r\n         elem (div n x) primosN] \/= []\r\n    where primosN = takeWhile (<=n) primos\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 4.1. [Problema 37 del proyecto Euler] Un n\u00famero primo es\r\n-- truncable si los n\u00fameros que se obtienen eliminado cifras, de derecha\r\n-- a izquierda, son primos. Por ejemplo, 599 es un primo truncable\r\n-- porque 599, 59 y 5 son primos; en cambio, 577 es un primo no\r\n-- truncable porque 57 no es primo.   \r\n-- \r\n-- Definir la funci\u00f3n \r\n--    primoTruncable :: Int -> Bool\r\n-- tal que (primoTruncable x) se verifica si x es un primo\r\n-- truncable. Por ejemplo,\r\n--    primoTruncable 599  ==  True\r\n--    primoTruncable 577  ==  False\r\n-- ---------------------------------------------------------------------\r\n\r\nprimoTruncable :: Int -> Bool\r\nprimoTruncable x \r\n    | x < 10    = primo x\r\n    | otherwise = primo x &#038;&#038; primoTruncable (x `div` 10)\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 4.2. Definir la funci\u00f3n\r\n--    sumaPrimosTruncables :: Int -> Int\r\n-- tal que (sumaPrimosTruncables n) es la suma de los n primeros primos\r\n-- truncables. Por ejemplo,\r\n--    sumaPrimosTruncables 10  ==  249\r\n-- Calcular la suma de los 20 primos truncables.\r\n-- ---------------------------------------------------------------------\r\n\r\nsumaPrimosTruncables :: Int -> Int\r\nsumaPrimosTruncables n = \r\n    sum (take n [x | x <- primos, primoTruncable x])\r\n\r\n-- El c\u00e1lculo es\r\n--    ghci> sumaPrimosTruncables 20\r\n--    2551\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 5.1. Definir la funci\u00f3n\r\n--    intercala :: a -> [a] -> [[a]]\r\n-- tal que (intercala x ys) es la lista de las listas obtenidas\r\n-- intercalando x entre los elementos de ys. Por ejemplo, \r\n--    intercala 1 [2,3]  ==  [[1,2,3],[2,1,3],[2,3,1]]\r\n-- ---------------------------------------------------------------------\r\n\r\nintercala :: a -> [a] -> [[a]]\r\nintercala x [] = [[x]]\r\nintercala x (y:ys) = (x:y:ys) : [y:zs | zs <- intercala x ys]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 5.2. Definir la funci\u00f3n \r\n--    permutaciones :: [a] -> [[a]]\r\n-- tal que (permutaciones xs) es la lista de las permutaciones de la\r\n-- lista xs. Por ejemplo, \r\n--    permutaciones \"bc\"   ==  [\"bc\",\"cb\"]\r\n--    permutaciones \"abc\"  ==  [\"abc\",\"bac\",\"bca\",\"acb\",\"cab\",\"cba\"]\r\n-- ---------------------------------------------------------------------\r\n\r\npermutaciones :: [a] -> [[a]]\r\npermutaciones []     = [[]]\r\npermutaciones (x:xs) = \r\n    concat [intercala x ys | ys <- permutaciones xs]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 5.3. Definir la funci\u00f3n\r\n--    permutacionesN :: Integer -> [Integer]\r\n-- tal que (permutacionesN x) es la lista de los n\u00fameros obtenidos\r\n-- permutando las cifras de x. Por ejemplo,\r\n--    permutacionesN 352  ==  [352,532,523,325,235,253]\r\n-- ---------------------------------------------------------------------\r\n\r\npermutacionesN :: Int -> [Int]\r\npermutacionesN x = [read ys | ys <- permutaciones (show x)]\r\n\r\n-- ---------------------------------------------------------------------\r\n-- Ejercicio 5.4. Un primo permutable es un n\u00famero primo tal que todos\r\n-- los n\u00fameros obtenidos permutando sus cifras son primos. Por ejemplo,\r\n-- 337 es un primo permutable ya que 337, 373 y 733 son primos. \r\n-- \r\n-- Definir la funci\u00f3n  \r\n--    primoPermutable :: Integer -> Bool\r\n-- tal que (primoPermutable x) se verifica si x es un primo\r\n-- permutable. Por ejemplo, \r\n--    primoPermutable 17  ==  True\r\n--    primoPermutable 19  ==  False\r\n-- ---------------------------------------------------------------------\r\n\r\nprimoPermutable :: Int -> Bool\r\nprimoPermutable x = and [primo y | y <- permutacionesN x]\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 comentando las soluciones de los ejercicios de evaluaci\u00f3n perezosa y listas infinitas de las relaciones 16 y 17. Los ejercicios, y sus soluciones, se muestran a continuaci\u00f3n. Los de la relaci\u00f3n 16 son<\/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":[1],"tags":[298],"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\/2523"}],"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=2523"}],"version-history":[{"count":4,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/2523\/revisions"}],"predecessor-version":[{"id":2687,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/2523\/revisions\/2687"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=2523"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=2523"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=2523"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}