I1M2018: Ejercicios de definiciones por comprensión (2)
En la primera parte de la clase de hoy del curso de Informática de 1º del Grado en Matemáticas se han comentado soluciones de 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 |
-- --------------------------------------------------------------------- -- Ejercicio 6 (Problema 1 del proyecto Euler) Definir la función -- euler1 :: Int -> Int -- tal que (euler1 n) es la suma de todos los múltiplos de 3 ó 5 menores -- que n. Por ejemplo, -- euler1 10 == 23 -- -- Calcular la suma de todos los múltiplos de 3 ó 5 menores que 1000. -- --------------------------------------------------------------------- euler1 :: Int -> Int euler1 n = sum [x | x <- [1..n-1], multiplo x 3 || multiplo x 5] where multiplo x y = mod x y == 0 -- Cálculo: -- ghci> euler1 1000 -- 233168 -- --------------------------------------------------------------------- -- Ejercicio 7. Definir la función -- circulo :: Int -> Int -- tal que (circulo n) es el la cantidad de pares de números naturales -- (x,y) que se encuentran dentro del círculo de radio n. Por ejemplo, -- circulo 3 == 9 -- circulo 4 == 15 -- circulo 5 == 22 -- circulo 100 == 7949 -- --------------------------------------------------------------------- circulo :: Int -> Int circulo n = length [(x,y) | x <- [0..n], y <- [0..n], x*x+y*y < n*n] -- La eficiencia puede mejorarse con circulo2 :: Int -> Int circulo2 n = length [(x,y) | x <- [0..n-1] , y <- [0..raizCuadradaEntera (n*n - x*x)] , x*x+y*y < n*n] -- (raizCuadradaEntera n) es la parte entera de la raíz cuadrada de -- n. Por ejemplo, -- raizCuadradaEntera 17 == 4 raizCuadradaEntera :: Int -> Int raizCuadradaEntera n = truncate (sqrt (fromIntegral n)) -- Comparación de eficiencia -- λ> circulo (10^4) -- 78549754 -- (73.44 secs, 44,350,688,480 bytes) -- λ> circulo2 (10^4) -- 78549754 -- (59.71 secs, 36,457,043,240 bytes) -- --------------------------------------------------------------------- -- Ejercicio 8.1. Definir la función -- aproxE :: Double -> [Double] -- tal que (aproXE n) es la lista cuyos elementos son los términos de la -- sucesión (1+1/m)**m desde 1 hasta n. Por ejemplo, -- aproxE 1 == [2.0] -- aproxE 4 == [2.0,2.25,2.37037037037037,2.44140625] -- --------------------------------------------------------------------- aproxE :: Double -> [Double] aproxE n = [(1+1/m)**m | m <- [1..n]] -- --------------------------------------------------------------------- -- Ejercicio 8.2. ¿Cuál es el límite de la sucesión (1+1/m)**m ? -- --------------------------------------------------------------------- -- El límite de la sucesión es el número e. -- --------------------------------------------------------------------- -- Ejercicio 8.3. Definir la función -- errorAproxE :: Double -> Double -- tal que (errorE x) es el menor número de términos de la sucesión -- (1+1/m)**m necesarios para obtener su límite con un error menor que -- x. Por ejemplo, -- errorAproxE 0.1 == 13.0 -- errorAproxE 0.01 == 135.0 -- errorAproxE 0.001 == 1359.0 -- Indicación: En Haskell, e se calcula como (exp 1). -- --------------------------------------------------------------------- errorAproxE :: Double -> Double errorAproxE x = head [m | m <- [1..], abs (exp 1 - (1+1/m)**m) < x] -- --------------------------------------------------------------------- -- Ejercicio 9.1. Definir la función -- aproxLimSeno :: Double -> [Double] -- tal que (aproxLimSeno n) es la lista cuyos elementos son los términos -- de la sucesión -- sen(1/m) -- -------- -- 1/m -- desde 1 hasta n. Por ejemplo, -- aproxLimSeno 1 == [0.8414709848078965] -- aproxLimSeno 2 == [0.8414709848078965,0.958851077208406] -- --------------------------------------------------------------------- aproxLimSeno :: Double -> [Double] aproxLimSeno n = [sin(1/m)/(1/m) | m <- [1..n]] -- --------------------------------------------------------------------- -- Ejercicio 9.2. ¿Cuál es el límite de la sucesión sen(1/m)/(1/m) ? -- --------------------------------------------------------------------- -- El límite es 1. -- --------------------------------------------------------------------- -- Ejercicio 9.3. Definir la función -- errorLimSeno :: Double -> Double -- tal que (errorLimSeno x) es el menor número de términos de la sucesión -- sen(1/m)/(1/m) necesarios para obtener su límite con un error menor -- que x. Por ejemplo, -- errorLimSeno 0.1 == 2.0 -- errorLimSeno 0.01 == 5.0 -- errorLimSeno 0.001 == 13.0 -- errorLimSeno 0.0001 == 41.0 -- --------------------------------------------------------------------- errorLimSeno :: Double -> Double errorLimSeno x = head [m | m <- [1..], abs (1 - sin(1/m)/(1/m)) < x] -- --------------------------------------------------------------------- -- Ejercicio 10.1. Definir la función -- calculaPi :: Double -> Double -- tal que (calculaPi n) es la aproximación del número pi calculada -- mediante la expresión -- 4*(1 - 1/3 + 1/5 - 1/7 + ...+ (-1)**n/(2*n+1)) -- Por ejemplo, -- calculaPi 3 == 2.8952380952380956 -- calculaPi 300 == 3.1449149035588526 -- --------------------------------------------------------------------- calculaPi :: Double -> Double calculaPi n = 4 * sum [(-1)**x/(2*x+1) | x <- [0..n]] -- --------------------------------------------------------------------- -- Ejercicio 10.2. Definir la función -- errorPi :: Double -> Double -- tal que (errorPi x) es el menor número de términos de la serie -- 4*(1 - 1/3 + 1/5 - 1/7 + ...+ (-1)**n/(2*n+1)) -- necesarios para obtener pi con un error menor que x. Por ejemplo, -- errorPi 0.1 == 9.0 -- errorPi 0.01 == 99.0 -- errorPi 0.001 == 999.0 -- --------------------------------------------------------------------- errorPi :: Double -> Double errorPi x = head [n | n <- [1..] , abs (pi - calculaPi n) < x] |
En la segunda parte se ha realizado un ejercicio de autoevaluación en el laboratorio.