I1M2013: Ejercicios sobre funciones de orden superior y plegados (2)
En la clase de hoy del curso Informática (de 1º de Grado en Matemáticas) se han comentado las soluciones de los ejercicios 6 a 11 de la 12ª relación. En los ejercicios se piden definiciones de funciones de orden superior y con plegados.
Los ejercicios y 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 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
-- --------------------------------------------------------------------- -- Importación de librerías auxiliares -- -- --------------------------------------------------------------------- import Test.QuickCheck -- --------------------------------------------------------------------- -- Ejercicio 6. Definir la función -- relacionados :: (a -> a -> Bool) -> [a] -> Bool -- tal que (relacionados r xs) se verifica si para todo par (x,y) de -- elementos consecutivos de xs se cumple la relación r. Por ejemplo, -- relacionados (<) [2,3,7,9] == True -- relacionados (<) [2,3,1,9] == False -- --------------------------------------------------------------------- relacionados :: (a -> a -> Bool) -> [a] -> Bool relacionados r (x:y:zs) = (r x y) && relacionados r (y:zs) relacionados _ _ = True -- Una definición alternativa es relacionados' :: (a -> a -> Bool) -> [a] -> Bool relacionados' r xs = and [r x y | (x,y) <- zip xs (tail xs)] -- --------------------------------------------------------------------- -- Ejercicio 7. Definir la función -- agrupa :: Eq a => [[a]] -> [[a]] -- tal que (agrupa xss) es la lista de las listas obtenidas agrupando -- los primeros elementos, los segundos, ... Por ejemplo, -- agrupa [[1..6],[7..9],[10..20]] == [[1,7,10],[2,8,11],[3,9,12]] -- agrupa [] == [] -- --------------------------------------------------------------------- agrupa :: Eq a => [[a]] -> [[a]] agrupa [] = [] agrupa xss | [] `elem` xss = [] | otherwise = primeros xss : agrupa (restos xss) where primeros = map head restos = map tail -- --------------------------------------------------------------------- -- Ejercicio 8.1. Definir por recursión la función -- superpar :: Int -> Bool -- tal que (superpar n) se verifica si n es un número par tal que todos -- sus dígitos son pares. Por ejemplo, -- superpar 426 == True -- superpar 456 == False -- --------------------------------------------------------------------- superpar :: Int -> Bool superpar n | n < 10 = even n | otherwise = even n && superpar (n `div` 10) -- Otra forma equivalente es superpar' :: Int -> Bool superpar' 0 = True superpar' n = even n && superpar' (div n 10) -- --------------------------------------------------------------------- -- Ejercicio 8.2. Definir por comprensión la función -- superpar2 :: Int -> Bool -- tal que (superpar2 n) se verifica si n es un número par tal que todos -- sus dígitos son pares. Por ejemplo, -- superpar2 426 == True -- superpar2 456 == False -- --------------------------------------------------------------------- superpar2 :: Int -> Bool superpar2 n = and [even d | d <- digitos n] digitos :: Int -> [Int] digitos n = [read [d] | d <- show n] -- --------------------------------------------------------------------- -- Ejercicio 8.3. Definir, por recursión sobre los dígitos, la función -- superpar3 :: Int -> Bool -- tal que (superpar3 n) se verifica si n es un número par tal que todos -- sus dígitos son pares. Por ejemplo, -- superpar3 426 == True -- superpar3 456 == False -- --------------------------------------------------------------------- superpar3 :: Int -> Bool superpar3 n = sonPares (digitos n) where sonPares [] = True sonPares (d:ds) = even d && sonPares ds -- --------------------------------------------------------------------- -- Ejercicio 8.3. Definir, usando all, la función -- superpar4 :: Int -> Bool -- tal que (superpar4 n) se verifica si n es un número par tal que todos -- sus dígitos son pares. Por ejemplo, -- superpar4 426 == True -- superpar4 456 == False -- --------------------------------------------------------------------- superpar4 :: Int -> Bool superpar4 n = all even (digitos n) -- --------------------------------------------------------------------- -- Ejercicio 8.5. Definir, usando filter, la función -- superpar5 :: Int -> Bool -- tal que (superpar5 n) se verifica si n es un número par tal que todos -- sus dígitos son pares. Por ejemplo, -- superpar5 426 == True -- superpar5 456 == False -- --------------------------------------------------------------------- superpar5 :: Int -> Bool superpar5 n = filter even (digitos n) == digitos n -- --------------------------------------------------------------------- -- Ejercicio 9. Se considera la función -- filtraAplica :: (a -> b) -> (a -> Bool) -> [a] -> [b] -- tal que (filtraAplica f p xs) es la lista obtenida aplicándole a los -- elementos de xs que cumplen el predicado p la función f. Por ejemplo, -- filtraAplica (4+) (<3) [1..7] => [5,6] -- Se pide, definir la función -- 1. por comprensión, -- 2. usando map y filter, -- 3. por recursión y -- 4. por plegado (con foldr). -- --------------------------------------------------------------------- -- La definición con lista de comprensión es filtraAplica_1 :: (a -> b) -> (a -> Bool) -> [a] -> [b] filtraAplica_1 f p xs = [f x | x <- xs, p x] -- La definición con map y filter es filtraAplica_2 :: (a -> b) -> (a -> Bool) -> [a] -> [b] filtraAplica_2 f p xs = map f (filter p xs) -- La definición por recursión es filtraAplica_3 :: (a -> b) -> (a -> Bool) -> [a] -> [b] filtraAplica_3 f p [] = [] filtraAplica_3 f p (x:xs) | p x = f x : filtraAplica_3 f p xs | otherwise = filtraAplica_3 f p xs -- La definición por plegado es filtraAplica_4 :: (a -> b) -> (a -> Bool) -> [a] -> [b] filtraAplica_4 f p = foldr g [] where g x y | p x = f x : y | otherwise = y -- La definición por plegado usando lambda es filtraAplica_4' :: (a -> b) -> (a -> Bool) -> [a] -> [b] filtraAplica_4' f p = foldr (\x y -> if p x then (f x : y) else y) [] -- --------------------------------------------------------------------- -- Ejercicio 10.1. Definir, mediante recursión, la función -- maximumR :: Ord a => [a] -> a -- tal que (maximumR xs) es el máximo de la lista xs. Por ejemplo, -- maximumR [3,7,2,5] == 7 -- maximumR ["todo","es","falso"] == "todo" -- maximumR ["menos","alguna","cosa"] == "menos" -- Nota: La función maximumR es equivalente a la predefinida maximum. -- --------------------------------------------------------------------- maximumR :: Ord a => [a] -> a maximumR [x] = x maximumR (x:y:ys) = max x (maximumR (y:ys)) -- --------------------------------------------------------------------- -- Ejercicio 10.2. La función de plegado foldr1 está definida por -- foldr1 :: (a -> a -> a) -> [a] -> a -- foldr1 _ [x] = x -- foldr1 f (x:xs) = f x (foldr1 f xs) -- -- Definir, mediante plegado con foldr1, la función -- maximumP :: Ord a => [a] -> a -- tal que (maximumR xs) es el máximo de la lista xs. Por ejemplo, -- maximumP [3,7,2,5] == 7 -- maximumP ["todo","es","falso"] == "todo" -- maximumP ["menos","alguna","cosa"] == "menos" -- Nota: La función maximumP es equivalente a la predefinida maximum. -- --------------------------------------------------------------------- maximumP :: Ord a => [a] -> a maximumP = foldr1 max -- --------------------------------------------------------------------- -- Ejercicio 11. Definir, mediante plegado con foldr1, la función -- minimunP :: Ord a => [a] -> a -- tal que (minimunR xs) es el máximo de la lista xs. Por ejemplo, -- minimunP [3,7,2,5] == 2 -- minimumP ["todo","es","falso"] == "es" -- minimumP ["menos","alguna","cosa"] == "alguna" -- Nota: La función minimunP es equivalente a la predefinida minimun. -- --------------------------------------------------------------------- minimumP :: Ord a => [a] -> a minimumP = foldr1 min |