Números alternados
Decimos que un número es alternado si no tiene dos cifras consecutivas iguales ni tres cifras consecutivas en orden creciente no estricto o decreciente no estricto. Por ejemplo, los números 132425 y 92745 son alternados, pero los números 12325 y 29778 no. Las tres primeras cifras de 12325 están en orden creciente y 29778 tiene dos cifras iguales consecutivas.
Definir la constante
1 |
alternados :: [Integer] |
cuyo valor es la lista infinita de los números alternados. Por ejemplo,
1 2 3 |
take 10 alternados == [0,1,2,3,4,5,6,7,8,9] length (takeWhile (< 1000) alternados) == 616 alternados !! 1234567 == 19390804 |
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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
import Data.Char (digitToInt) -- 1ª definición -- ============= -- (cifras n) es la lista de las cifras de n. Por ejemplo. -- cifras 325 == [3,2,5] cifras :: Integer -> [Int] cifras n = map digitToInt (show n) -- (cifrasAlternadas xs) se verifica si las lista de cifras xs es -- alternada. Por ejemplo, -- cifrasAlternadas [1,3,2,4,2,5] == True -- cifrasAlternadas [9,2,7,4,5] == True -- cifrasAlternadas [1,2,3,2,5] == False -- cifrasAlternadas [2,9,7,7,8] == False cifrasAlternadas :: [Int] -> Bool cifrasAlternadas [x1,x2] = x1 /= x2 cifrasAlternadas (x1:x2:x3:xs) = not (((x1 <= x2) && (x2 <= x3)) || ((x1 >= x2) && (x2 >= x3))) && cifrasAlternadas (x2:x3:xs) cifrasAlternadas _ = True -- (alternado n) se verifica si n es un número alternado. Por ejemplo, -- alternado 132425 == True -- alternado 92745 == True -- alternado 12325 == False -- alternado 29778 == False alternado :: Integer -> Bool alternado n = cifrasAlternadas (cifras n) alternados1 :: [Integer] alternados1 = filter alternado [0..] -- 2ª definición -- ============= -- (extiendeAlternado n) es la lista de números alternados que se pueden -- obtener añadiendo una cifra al final del número alternado n. Por -- ejemplo, -- extiendeAlternado 7 == [70,71,72,73,74,75,76,78,79] -- extiendeAlternado 24 == [240,241,242,243] -- extiendeAlternado 42 == [423,424,425,426,427,428,429] extiendeAlternado :: Integer -> [Integer] extiendeAlternado n | n < 10 = [n*10+h | h <- [0..n-1]++[n+1..9]] | d < c = [n*10+h | h <- [0..c-1]] | otherwise = [n*10+h | h <- [c+1..9]] where c = n `mod` 10 d = (n `mod` 100) `div` 10 alternados2 :: [Integer] alternados2 = concat (iterate (concatMap extiendeAlternado) [0]) |
3 Comentarios