I1M2012: Ejercicios sobre el 2013 y funciones de orden superior
En la clase de hoy de Informática de 1º del Grado en Matemáticas hemos comentado las soluciones de los 3 primeros ejercicios de la 13ª relación (de propiedades del 2013) y los 3 primeros ejercicios de la 14ª relación (de funciones de orden superior).
Los ejercicios, y sus soluciones, se muestran a continuación: Los de la 13ª relación son
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 |
-- --------------------------------------------------------------------- -- Importación de librerías auxiliares -- -- --------------------------------------------------------------------- import Data.List -- --------------------------------------------------------------------- -- Ejercicio 1. [Potencias de 2013] En los apartados de este ejercicio -- se resuelven problemas sobre potencias del 2013 como los siguientes: -- (a) ¿Cuál es el menor n, tal que n aparece en 2013^n en la posición -- n? -- (b) ¿Cuál es el menor n (mayor que 1), tal que dentro 2013^n aparece -- el 2013? ¿En qué posición aparece? -- --------------------------------------------------------------------- -- --------------------------------------------------------------------- -- Ejercicio 1.1. Definir la función -- posiciones :: Eq a => [a] -> [a] -> [Int] -- tal que (posiciones xs ys) es la lista de las posiciones que ocupa xs -- dentro de ys. Por ejemplo, -- posiciones "ac" "bacdacaec" == [2,5] -- --------------------------------------------------------------------- posiciones :: Eq a => [a] -> [a] -> [Int] posiciones xs ys = aux ys 1 where aux [] n = [] aux (y:ys) n | isPrefixOf xs (y:ys) = n : aux ys (n+1) | otherwise = aux ys (n+1) -- --------------------------------------------------------------------- -- Ejercicio 1.2. Definir la función -- posicionesEnPotencia :: Integer -> Integer -> [Int] -- tal que (posicionesEnPotencia n m) es la lista de las posiciones del -- número n en 2013^m. Por ejemplo, -- posicionesEnPotencia 1 1 == [3] -- posicionesEnPotencia 2 2 == [4] -- posicionesEnPotencia 3 3 == [] -- posicionesEnPotencia 4 4 == [3,11] -- posicionesEnPotencia 5 5 == [4,11] -- posicionesEnPotencia 6 6 == [1,2,5] -- posicionesEnPotencia 58 58 == [26,32,55,59,79] -- --------------------------------------------------------------------- posicionesEnPotencia :: Integer -> Integer -> [Int] posicionesEnPotencia n m = posiciones (show n) (show (2013^m)) -- --------------------------------------------------------------------- -- Ejercicio 1.3. Definir el ejercicio -- enPosicion :: Eq a => [a] -> [a] -> Int -> Bool -- tal que (enPosicion xs ys n) se verifica si xs está en ys en la -- posición n. Por ejemplo, -- enPosicion "ab" "cabdab" 2 == True -- enPosicion "ab" "cabdab" 5 == True -- enPosicion "ab" "cabdab" 4 == False -- --------------------------------------------------------------------- enPosicion :: Eq a => [a] -> [a] -> Int -> Bool enPosicion xs ys n = isPrefixOf xs (drop (n-1) ys) -- --------------------------------------------------------------------- -- Ejercicio 1.4. Definir el ejercicio -- enPosicionPotencia :: Integer -> Integer -> Int -> Bool -- tal que (enPosicionPotencia x y n) se verifica si x está en 2013^y en -- la posición n. Por ejemplo, -- enPosicionPotencia 4 4 3 == True -- enPosicionPotencia 4 4 5 == False -- --------------------------------------------------------------------- enPosicionPotencia :: Integer -> Integer -> Int -> Bool enPosicionPotencia x y n = enPosicion (show x) (show (2013^y)) n -- --------------------------------------------------------------------- -- Ejercicio 1.5. Calcular el menor n, tal que n aparece en la posición -- n de 2013^n. -- --------------------------------------------------------------------- menorFijo :: Integer menorFijo = head [n | n <- [1..], enPosicionPotencia n n (fromIntegral n)] -- El cálculo es -- ghci> menorFijo -- 83 -- --------------------------------------------------------------------- -- Ejercicio 1.6. Calcular el menor n (mayor que 1), tal que dentro -- 2013^n aparezca el 2013. ¿En qué posición aparece el 2013? -- --------------------------------------------------------------------- menorPotenciaConteniendo2013 :: Integer menorPotenciaConteniendo2013 = head [n | n <- [2..], not (null (posicionesEnPotencia 2013 n))] -- El cálculo es -- ghci> menorPotenciaConteniendo2013 -- 98 -- ghci> posicionesEnPotencia 2013 98 -- [23,170] -- --------------------------------------------------------------------- -- Ejercicio 2. [2013 en factoriales] Con los apartados de este -- ejercicio se resuelve el siguiente problema: -- ¿Cuál es el primer factorial que tiene a "2013" dentro? -- --------------------------------------------------------------------- -- --------------------------------------------------------------------- -- Ejercicio 2.1. Definir la función -- fact :: Int -> Int -- tal que (fact n) es el factorial de n. Por ejemplo, -- fact 5 == 120 -- fact 18 == 6402373705728000 -- --------------------------------------------------------------------- fact :: Integer -> Integer fact n = product [1..n] -- --------------------------------------------------------------------- -- Ejercicio 2.2. Definir la función -- enFactorial :: Int -> Bool -- tal que (enFactorial n) es el menor x tal que x ocurre dentro del -- factorial de x. Por ejemplo, -- enFactorial 20 == 5 -- enFactorial 23 == 18 -- --------------------------------------------------------------------- enFactorial :: Integer -> Integer enFactorial n = head [x | x <- [0..], isInfixOf (show n) (show (fact x))] -- --------------------------------------------------------------------- -- Ejercicio 2.3. Calcular el menor n tal que 2013 ocurre dentro del -- factorial de n. ¿Qué posición ocupa? -- --------------------------------------------------------------------- -- El cálculo es -- ghci> enFactorial 2013 -- 68 -- ghci> fact 68 -- 24800355424368305996009904185691715810473992013553676723717 -- 10738018221445712183296000000000000000 -- ghci> posiciones (show 2013) (show (fact 68)) -- [44] -- --------------------------------------------------------------------- -- Ejercicio 3. [2013 en potencias de 2] Con los apartados de este -- ejercicio se resuelve el siguiente problema -- ¿Cuál es la primer potencia de 2 que tiene "2013" dentro? ¿y las -- siguientes? -- --------------------------------------------------------------------- -- --------------------------------------------------------------------- -- Ejercicio 3.1. Definir la función -- enPotenciaDeDos :: Integer -> [Integer] -- tal que (enPotenciaDeDos n) es la lista de los números x tales que n -- aparece dentro de 2^n. Por ejemplo, -- head (enPotenciaDeDos 21) == 18 -- 2^18 == 262144 -- --------------------------------------------------------------------- enPotenciaDeDos :: Integer -> [Integer] enPotenciaDeDos n = [x | x <- [0..], isInfixOf (show n) (show (2^x))] -- --------------------------------------------------------------------- -- Ejercicio 3.2. Calcular los 10 primeros números x tales que 2013 -- aparece dentro de 2^x. -- --------------------------------------------------------------------- -- El cálculo es -- ghci> take 10 (enPotenciaDeDos 2013) -- [163,310,613,619,643,644,702,736,784,865] |
y los de la 14ª relación son
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 |
-- --------------------------------------------------------------------- -- Importación de librerías auxiliares -- -- --------------------------------------------------------------------- import Test.QuickCheck -- --------------------------------------------------------------------- -- Ejercicio 1. Redefinir por recursión la función -- takeWhile :: (a -> Bool) -> [a] -> [a] -- tal que (takeWhile p xs) es la lista de los elemento de xs hasta el -- primero que no cumple la propiedad p. Por ejemplo, -- takeWhile' (<7) [2,3,9,4,5] == [2,3] -- --------------------------------------------------------------------- takeWhile' :: (a -> Bool) -> [a] -> [a] takeWhile' _ [] = [] takeWhile' p (x:xs) | p x = x : takeWhile' p xs | otherwise = [] -- --------------------------------------------------------------------- -- Ejercicio 2. Redefinir por recursión la función -- dropWhile :: (a -> Bool) -> [a] -> [a] -- tal que (dropWhile p xs) es la lista de eliminando los elemento de xs -- hasta el primero que cumple la propiedad p. Por ejemplo, -- dropWhile' (<7) [2,3,9,4,5] == [9,4,5] -- --------------------------------------------------------------------- dropWhile' :: (a -> Bool) -> [a] -> [a] dropWhile' _ [] = [] dropWhile' p (x:xs) | p x = dropWhile' p xs | otherwise = x:xs -- --------------------------------------------------------------------- -- Ejercicio 3. Redefinir, usando foldr, la función concat. Por ejemplo, -- concat' [[1,3],[2,4,6],[1,9]] == [1,3,2,4,6,1,9] -- --------------------------------------------------------------------- -- La definición por recursión es concatR :: [[a]] -> [a] concatR [] = [] concatR (xs:xss) = xs ++ concatR xss -- La definición por plegado es concat' :: [[a]] -> [a] concat' = foldr (++) [] |