Distancia invierte y suma hasta capicúa
Un número es capicúa si es igual leído de izquierda a derecha que de derecha a izquierda; por ejemplo, el 4884.
El transformado «invierte y suma» de un número x es la suma de x y su número invertido; es decir, el número resultante de la inversión del orden en el que aparecen sus dígitos. Por ejemplo, el transformado de 124 es 124 + 421 = 545.
Se aplica la transformación «invierte y suma» hasta obtener un capicúa. Por ejemplo, partiendo del número 87, el proceso es
1 2 3 4 |
87 + 78 = 165 165 + 561 = 726 726 + 627 = 1353 1353 + 3531 = 4884 |
El número de pasos de dicho proceso es la distancia capicúa del número; por ejemplo, la distancia capicúa de 87 es 4.
Definir la función
1 |
distanciaIS :: Integer -> Integer |
tal que (distanciaIS x) es la distancia capicúa de x. Por ejemplo,
1 2 3 4 5 6 7 8 9 10 |
distanciaIS 11 == 0 distanciaIS 10 == 1 distanciaIS 19 == 2 distanciaIS 59 == 3 distanciaIS 69 == 4 distanciaIS 166 == 5 distanciaIS 79 == 6 distanciaIS 89 == 24 distanciaIS 10911 == 55 distanciaIS 1000000079994144385 == 259 |
Soluciones
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 |
import Data.List (genericLength) -- 1ª solución (por recursión) -- =========================== distanciaIS1 :: Integer -> Integer distanciaIS1 = genericLength . cadena -- (cadena x) es la lista de transformados de x que no son capicúas. Por -- ejemplo, -- cadena 87 == [87,165,726,1353] cadena :: Integer -> [Integer] cadena x | esCapicua x = [] | otherwise = x : cadena (transformadoIS x) -- (esCapicua x) se verifica si x es capicúa. Por ejemplo, -- esCapicua 42524 == True -- esCapicua 42542 == False esCapicua :: Integer -> Bool esCapicua x = show x == reverse (show x) -- (transformadoIS x) es el número obtenido sumándole a x el número con los -- mismos dígitos que x pero en orden inverso. Por ejemplo, -- transformadoIS 1325 == 6556 -- transformadoIS 1375 == 7106 transformadoIS :: Integer -> Integer transformadoIS x = x + read (reverse (show x)) -- 2ª solución (por recursión con contador) distanciaIS2 :: Integer -> Integer distanciaIS2 x = aux x 0 where aux x n | esCapicua x = n | otherwise = aux (transformadoIS x) (n+1) -- 3ª solución (con iterate) distanciaIS3 :: Integer -> Integer distanciaIS3 = genericLength . takeWhile (not . esCapicua) . iterate transformadoIS |
Como curiosidad dejo el enlace de este maravilloso post de gaussianos que trata sobre este algoritmo y de los números que, posiblemente, no produzcan nunca un capicúa con él (números de Lychrel). Aun no se ha demostrado si tales números existen o no. Pero con el número 196, Wade VanLandingham consiguió llegar después de 724756966 iteraciones hasta un número de 300 millones de dígitos…y todavía no era capicúa. Como este es el primer número con el que ocurre, el algoritmo f(x) = x + (x con los dígitos invertidos) se llama algoritmo 196.
http://gaussianos.com/la-conjetura-del-196/