I1M2018: Ejercicios de definiciones por comprensión (1)
En la clase de hoy del curso de Informática de 1º del Grado en Matemáticas se han comentado soluciones de los primeros ejercicios de la 3ª relación sobre definiciones por comprensión.
Los ejercicios y su solución se muestran a continuación
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
-- --------------------------------------------------------------------- -- Introducción -- -- --------------------------------------------------------------------- -- En esta relación se presentan ejercicios con definiciones por -- comprensión correspondientes al tema 5 que se encuentra -- http://www.cs.us.es/~jalonso/cursos/i1m-18temas/tema-5.html -- --------------------------------------------------------------------- -- Ejercicio 1. Definir, por comprensión, la función -- sumaDeCuadrados :: Integer -> Integer -- tal que (sumaDeCuadrados n) es la suma de los cuadrados de los -- primeros n números; es decir, 1^2 + 2^2 + ... + n^2. Por ejemplo, -- sumaDeCuadrados 3 == 14 -- sumaDeCuadrados 100 == 338350 -- --------------------------------------------------------------------- sumaDeCuadrados :: Integer -> Integer sumaDeCuadrados n = sum [x^2 | x <- [1..n]] -- --------------------------------------------------------------------- -- Ejercicio 2. Definir por comprensión la función -- replica :: Int -> a -> [a] -- tal que (replica n x) es la lista formada por n copias del elemento -- x. Por ejemplo, -- replica 4 7 == [7,7,7,7] -- replica 3 True == [True, True, True] -- Nota: La función replica es equivalente a la predefinida replicate. -- --------------------------------------------------------------------- replica :: Int -> a -> [a] replica n x = [x | _ <- [1..n]] -- --------------------------------------------------------------------- -- Ejercicio 3.1. Definir la función -- suma :: Integer -> Integer -- tal (suma n) es la suma de los n primeros números. Por ejemplo, -- suma 3 == 6 -- --------------------------------------------------------------------- suma :: Integer -> Integer suma n = sum [1..n] -- Otra definición más eficiente es suma2 :: Integer -> Integer suma2 n = (1+n)*n `div` 2 -- --------------------------------------------------------------------- -- Ejercicio 3.2. Los triángulos aritméticos se forman como sigue -- 1 -- 2 3 -- 4 5 6 -- 7 8 9 10 -- 11 12 13 14 15 -- 16 17 18 19 20 21 -- -- Definir la función -- linea :: Integer -> [Integer] -- tal que (linea n) es la línea n-ésima de los triángulos -- aritméticos. Por ejemplo, -- linea 4 == [7,8,9,10] -- linea 5 == [11,12,13,14,15] -- --------------------------------------------------------------------- linea :: Integer -> [Integer] linea n = [suma (n-1)+1..suma n] -- La definición puede mejorarse linea2 :: Integer -> [Integer] linea2 n = [s+1..s+n] where s = suma (n-1) -- Una variante más eficiente es linea3 :: Integer -> [Integer] linea3 n = [s+1..s+n] where s = suma2 (n-1) -- La mejora de la eficiencia se puede observar como sigue: -- ghci> :set +s -- ghci> head (linea 1000000) -- 499999500001 -- (17.94 secs, 309207420 bytes) -- ghci> head (linea3 1000000) -- 499999500001 -- (0.01 secs, 525496 bytes) -- --------------------------------------------------------------------- -- Ejercicio 3.3. Definir la función -- triangulo :: Integer -> [[Integer]] -- tal que (triangulo n) es el triángulo aritmético de altura n. Por -- ejemplo, -- triangulo 3 == [[1],[2,3],[4,5,6]] -- triangulo 4 == [[1],[2,3],[4,5,6],[7,8,9,10]] -- --------------------------------------------------------------------- triangulo :: Integer -> [[Integer]] triangulo n = [linea m | m <- [1..n]] -- --------------------------------------------------------------------- -- Ejercicio 4. Un entero positivo es perfecto si es igual a la suma de -- sus factores, excluyendo el propio número. -- -- Definir por comprensión la función -- perfectos :: Int -> [Int] -- tal que (perfectos n) es la lista de todos los números perfectos -- menores que n. Por ejemplo, -- perfectos 500 == [6,28,496] -- Indicación: Usar la función factores del tema 5. -- --------------------------------------------------------------------- -- La función factores del tema es factores :: Int -> [Int] factores n = [x | x <- [1..n], n `mod` x == 0] -- La definición es perfectos :: Int -> [Int] perfectos n = [x | x <- [1..n], sum (init (factores x)) == x] -- --------------------------------------------------------------------- -- Ejercicio 5.1. Un número natural n se denomina abundante si es menor -- que la suma de sus divisores propios. Por ejemplo, 12 y 30 son -- abundantes pero 5 y 28 no lo son. -- -- Definir la función -- numeroAbundante :: Int -> Bool -- tal que (numeroAbundante n) se verifica si n es un número -- abundante. Por ejemplo, -- numeroAbundante 5 == False -- numeroAbundante 12 == True -- numeroAbundante 28 == False -- numeroAbundante 30 == True -- --------------------------------------------------------------------- divisores :: Int -> [Int] divisores n = [m | m <- [1..n-1], n `mod` m == 0] numeroAbundante :: Int -> Bool numeroAbundante n = n < sum (divisores n) -- --------------------------------------------------------------------- -- Ejercicio 5.2. Definir la función -- numerosAbundantesMenores :: Int -> [Int] -- tal que (numerosAbundantesMenores n) es la lista de números -- abundantes menores o iguales que n. Por ejemplo, -- numerosAbundantesMenores 50 == [12,18,20,24,30,36,40,42,48] -- numerosAbundantesMenores 48 == [12,18,20,24,30,36,40,42,48] -- --------------------------------------------------------------------- numerosAbundantesMenores :: Int -> [Int] numerosAbundantesMenores n = [x | x <- [1..n], numeroAbundante x] -- --------------------------------------------------------------------- -- Ejercicio 5.3. Definir la función -- todosPares :: Int -> Bool -- tal que (todosPares n) se verifica si todos los números abundantes -- menores o iguales que n son pares. Por ejemplo, -- todosPares 10 == True -- todosPares 100 == True -- todosPares 1000 == False -- --------------------------------------------------------------------- todosPares :: Int -> Bool todosPares n = and [even x | x <- numerosAbundantesMenores n] -- --------------------------------------------------------------------- -- Ejercicio 5.4. Definir la constante -- primerAbundanteImpar :: Int -- que calcule el primer número natural abundante impar. Determinar el -- valor de dicho número. -- --------------------------------------------------------------------- primerAbundanteImpar :: Int primerAbundanteImpar = head [x | x <- [1,3..], numeroAbundante x] -- Su cálculo es -- ghci> primerAbundanteImpar -- 945 |