I1M2011: Funciones de orden superior y ejercicios de recursión y comprensión en Haskell
La clase de hoy de Informática de 1º del Grado en Matemáticas ha tenido dos partes.
En la primera parte hemos visto cómo pueden definirse funciones de orden superior en Haskell y su aplicación para definir las funciones de procesamiento de listas (map y filter). Las transparencias usadas en la clase son las 13 primeras del tema 7
En la segunda parte, hemos continuado comentado las soluciones de ejercicios de la 7ª relación que comenzamos en la clase anterior. Los ejercicios, y sus soluciones, 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 |
-- --------------------------------------------------------------------- -- Ejercicio 8.1. Definir, por recursión, la función -- pegaNumerosR :: Integer -> Integer -> Integer -- tal que (pegaNumerosR x y) es el número resultante de "pegar" los -- números x e y. Por ejemplo, -- pegaNumerosR 12 987 == 12987 -- pegaNumerosR 1204 7 == 12047 -- pegaNumerosR 100 100 == 100100 -- --------------------------------------------------------------------- pegaNumerosR :: Integer -> Integer -> Integer pegaNumerosR x y | y < 10 = 10*x+y | otherwise = 10 * pegaNumerosR x (y `div`10) + (y `mod` 10) -- --------------------------------------------------------------------- -- Ejercicio 8.2. Definir, sin usar recursión, la función -- pegaNumerosNR :: Integer -> Integer -> Integer -- tal que (pegaNumerosNR x y) es el número resultante de "pegar" los -- números x e y. Por ejemplo, -- pegaNumerosNR 12 987 == 12987 -- pegaNumerosNR 1204 7 == 12047 -- pegaNumerosNR 100 100 == 100100 -- --------------------------------------------------------------------- pegaNumerosNR :: Integer -> Integer -> Integer pegaNumerosNR x y = listaNumeroC (cifras x ++ cifras y) -- --------------------------------------------------------------------- -- Ejercicio 8.3. Comprobar con QuickCheck que las funciones -- pegaNumerosR y pegaNumerosNR son equivalentes. -- --------------------------------------------------------------------- -- La propiedad es prop_pegaNumeros x y = x >= 0 && y >= 0 ==> pegaNumerosR x y == pegaNumerosNR x y -- La comprobción es -- *Main> quickCheck prop_pegaNumeros -- +++ OK, passed 100 tests. -- --------------------------------------------------------------------- -- Ejercicio 9.1. Definir, por recursión, la función -- primeraCifraR :: Integer -> Integer -- tal que (primeraCifraR n) es la primera cifra de n. Por ejemplo, -- primeraCifraR 425 == 4 -- --------------------------------------------------------------------- primeraCifraR :: Integer -> Integer primeraCifraR n | n < 10 = n | otherwise = primeraCifraR (n `div` 10) -- --------------------------------------------------------------------- -- Ejercicio 9.2. Definir, sin usar recursión, la función -- primeraCifraNR :: Integer -> Integer -- tal que (primeraCifraNR n) es la primera cifra de n. Por ejemplo, -- primeraCifraNR 425 == 4 -- --------------------------------------------------------------------- primeraCifraNR :: Integer -> Integer primeraCifraNR n = head (cifras n) -- --------------------------------------------------------------------- -- Ejercicio 9.3. Comprobar con QuickCheck que las funciones -- primeraCifraR y primeraCifraNR son equivalentes. -- --------------------------------------------------------------------- -- La propiedad es prop_primeraCifra x = x >= 0 ==> primeraCifraR x == primeraCifraNR x -- La comprobación es -- *Main> quickCheck prop_primeraCifra -- +++ OK, passed 100 tests. -- --------------------------------------------------------------------- -- Ejercicio 10. Definir la función -- ultimaCifra :: Integer -> Integer -- tal que (ultimaCifra n) es la última cifra de n. Por ejemplo, -- ultimaCifra 425 == 5 -- --------------------------------------------------------------------- ultimaCifra :: Integer -> Integer ultimaCifra n = n `rem` 10 -- --------------------------------------------------------------------- -- Ejercicio 11.1. Definir la función -- inverso :: Integer -> Integer -- tal que (inverso n) es el número obtenido escribiendo las cifras de n -- en orden inverso. Por ejemplo, -- inverso 42578 == 87524 -- inverso 203 == 302 -- --------------------------------------------------------------------- inverso :: Integer -> Integer inverso n = listaNumeroC (reverse (cifras n)) -- --------------------------------------------------------------------- -- Ejercicio 11.2. Definir, usando show y read, la función -- inverso' :: Integer -> Integer -- tal que (inverso' n) es el número obtenido escribiendo las cifras de n -- en orden inverso'. Por ejemplo, -- inverso' 42578 == 87524 -- inverso' 203 == 302 -- --------------------------------------------------------------------- inverso' :: Integer -> Integer inverso' n = read (reverse (show n)) -- --------------------------------------------------------------------- -- Ejercicio 11.3. Comprobar con QuickCheck que las funciones -- inverso e inverso' son equivalentes. -- --------------------------------------------------------------------- -- La propiedad es prop_inverso n = n >= 0 ==> inverso n == inverso' n -- La comprobación es -- *Main> quickCheck prop_inverso -- +++ OK, passed 100 tests. -- --------------------------------------------------------------------- -- Ejercicio 12. Definir la función -- capicua :: Integer -> Bool -- tal que (capicua n) se verifica si si las cifras que n son las mismas -- de izquierda a derecha que de derecha a izquierda. Por ejemplo, -- capicua 1234 = False -- capicua 1221 = True -- capicua 4 = True -- --------------------------------------------------------------------- capicua :: Integer -> Bool capicua n = n == inverso n -- --------------------------------------------------------------------- -- Ejercicio 13.1. Definir, por recursión, la función -- mayorExponenteR :: Integer -> Integer -> Integer -- tal que (mayorExponenteR a b) es el exponente de la mayor potencia de -- a que divide b. Por ejemplo, -- mayorExponenteR 2 8 == 3 -- mayorExponenteR 2 9 == 0 -- mayorExponenteR 5 100 == 2 -- mayorExponenteR 2 60 == 2 -- --------------------------------------------------------------------- mayorExponenteR :: Integer -> Integer -> Integer mayorExponenteR a b | mod b a /= 0 = 0 | otherwise = 1 + mayorExponenteR a (b `div` a) -- --------------------------------------------------------------------- -- Ejercicio 13.2. Definir, por recursión, la función -- mayorExponenteC :: Integer -> Integer -> Integer -- tal que (mayorExponenteC a b) es el exponente de la mayor potencia de -- a que divide a b. Por ejemplo, -- mayorExponenteC 2 8 == 3 -- mayorExponenteC 5 100 == 2 -- mayorExponenteC 5 101 == 0 -- --------------------------------------------------------------------- mayorExponenteC :: Integer -> Integer -> Integer mayorExponenteC a b = head [x-1 | x <- [0..], mod b (a^x) /= 0] |