“El próximo después de 1811” con Haskell
El enunciado del problema de hoy de Números y algo más … es el siguiente
1811 fue el último año que no teniendo ceros en su composición, tanto su suma digital como su producto digital están incluidos como cadenas dentro del número
Suma digital (1811) = 1+8+1+1 = 11
Producto dígital (1811) = 1x8x1x1 = 8¿Cuál es próximo año sin ceros en que esto ocurrirá?
A partir del problema he escrito la siguinte relación de ejercicios para la asignatura de Informática de 1º del Grado en Matemáticas.
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 |
-- --------------------------------------------------------------------- -- Importación de librerías auxiliares -- -- --------------------------------------------------------------------- import Data.Char import Data.List -- --------------------------------------------------------------------- -- Ejercicio 1. Definir la función -- cifras :: Int -> [Int] -- tal que (cifras x) es la lista de las cifras de x. Por ejemplo, -- cifras 1811 == [1,8,1,1] -- --------------------------------------------------------------------- cifras :: Int -> [Int] cifras x = [digitToInt y | y <- show x] -- --------------------------------------------------------------------- -- Ejercicio 2. Definir la función -- sumaDigital :: Int -> Int -- tal que (sumaDigital x) es la suma de las cifras de x. Por ejemplo, -- sumaDigital 1811 == 11 -- --------------------------------------------------------------------- sumaDigital :: Int -> Int sumaDigital = sum . cifras -- --------------------------------------------------------------------- -- Ejercicio 3. Definir la función -- productoDigital :: Int -> Int -- tal que (sumaDigital x) es la suma de las cifras de x. Por ejemplo, -- productoDigital 1811 == 8 -- --------------------------------------------------------------------- productoDigital :: Int -> Int productoDigital = product . cifras -- --------------------------------------------------------------------- -- Ejercicio 4. Definir la función -- esSubcadena :: Eq a => [a] -> [a] -> Bool -- tal que (esSubcadena xs ys) se verifica si xs es subcadena de xs. Por -- ejemplo, -- esSubcadena "11" "18113" == True -- esSubcadena "83" "18113" == False -- --------------------------------------------------------------------- -- Una definición, usando inits y tails, es esSubcadena1 :: Eq a => [a] -> [a] -> Bool esSubcadena1 xs ys = or [elem xs (inits zs) | zs <- tails ys] -- Otra definición, usando isPrefixOf, es esSubcadena2 :: Eq a => [a] -> [a] -> Bool esSubcadena2 xs ys = or [isPrefixOf xs zs | zs <- tails ys] -- Otra definición, usando isInfixOf, es esSubcadena3 :: Eq a => [a] -> [a] -> Bool esSubcadena3 = isInfixOf -- En lo sucesivo, usaremos la tercera definición esSubcadena :: Eq a => [a] -> [a] -> Bool esSubcadena = esSubcadena3 -- --------------------------------------------------------------------- -- Ejercicio 5. Definir la constante -- numerosEspeciales :: [Int] -- tal que numerosEspeciales es la lista de los números que no teniendo -- ceros en su composición, tanto su suma digital como su producto -- digital están incluidos como cadenas dentro del número. Por ejemplo, -- take 10 numerosEspeciales == [1,2,3,4,5,6,7,8,9,119] -- --------------------------------------------------------------------- numerosEspeciales :: [Int] numerosEspeciales = [x | x <- [1..], let cifras' = cifras x, notElem 0 cifras', esSubcadena (cifras (sumaDigital x)) cifras', esSubcadena (cifras (productoDigital x)) cifras'] -- --------------------------------------------------------------------- -- Ejercicio 6. Definir, usando numerosEspeciales, la función -- siguienteNumeroEspecial :: Int -> Int -- tal que (siguienteNumeroEspecial x) es el menor número especial mayor -- que x. Por ejemplo, -- siguienteNumeroEspecial 9 == 119 -- --------------------------------------------------------------------- siguienteNumeroEspecial :: Int -> Int siguienteNumeroEspecial x = head (dropWhile (<=x) numerosEspeciales) -- --------------------------------------------------------------------- -- Ejercicio 7. Calcular el próximo año año que no teniendo ceros en su -- composición, tanto su suma digital como su producto digital están -- incluidos como cadenas dentro del número. -- --------------------------------------------------------------------- -- El cálculo es -- ghci> siguienteNumeroEspecial 2011 -- 3612 |