Sumas de dos capicúas
Definir las funciones
sumas2Capicuas :: Integer -> [(Integer, Integer)] noSuma2Capicuas :: [Integer]
tales que
- (sumas2Capicuas x) es la lista de las descomposiciones de x como suma de dos capicúas (con el primer sumando menor o igual que el segundo). Por ejemplo,
sumas2Capicuas 17 == [(6,11),(8,9)] sumas2Capicuas 187 == [(6,181),(66,121),(88,99)] sumas2Capicuas 165 == [(4,161),(44,121),(66,99),(77,88)] sumas2Capicuas 382 == [(9,373),(191,191)] sumas2Capicuas 151 == [(0,151)] sumas2Capicuas 201 == []
- noSuma2Capicuas es la sucesión de los números que no se pueden escribir como suma de dos capicúas. Por ejemplo,
λ> take 15 noSuma2Capicuas [21,32,43,54,65,76,87,98,201,1031,1041,1042,1051,1052,1053] λ> noSuma2Capicuas !! 3000 19941
Soluciones
sumas2Capicuas :: Integer -> [(Integer, Integer)] sumas2Capicuas x = [(y,z) | y <- takeWhile (<= (x `div` 2)) capicuas , let z = x - y , esCapicua z] -- capicuas es la sucesión de los números capicúas. Por ejemplo, -- λ> take 45 capicuas -- [0,1,2,3,4,5,6,7,8,9,11,22,33,44,55,66,77,88,99,101,111,121,131, -- 141,151,161,171,181,191,202,212,222,232,242,252,262,272,282,292, -- 303,313,323,333,343,353] -- Se usará la 2ª definición del ejercicio "Sucesión de capicúas". capicuas :: [Integer] capicuas = capicuasImpares `mezcla` capicuasPares -- capicuasPares es la sucesión del cero y las capicúas con un número -- par de dígitos. Por ejemplo, -- λ> take 17 capicuasPares -- [0,11,22,33,44,55,66,77,88,99,1001,1111,1221,1331,1441,1551,1661] capicuasPares :: [Integer] capicuasPares = [read (ns ++ reverse ns) | n <- [0..] , let ns = show n] -- capicuasImpares es la sucesión de las capicúas con un número -- impar de dígitos a partir de 1. Por ejemplo, -- λ> take 20 capicuasImpares -- [1,2,3,4,5,6,7,8,9,101,111,121,131,141,151,161,171,181,191,202] capicuasImpares :: [Integer] capicuasImpares = [1..9] ++ [read (ns ++ [z] ++ reverse ns) | n <- [1..] , let ns = show n , z <- "0123456789"] -- (mezcla xs ys) es la lista ordenada obtenida mezclando las dos listas -- ordenadas xs e ys, suponiendo que ambas son infinitas y con elementos -- distintos. Por ejemplo, -- take 10 (mezcla [2,12..] [5,15..]) == [2,5,12,15,22,25,32,35,42,45] -- take 10 (mezcla [2,22..] [5,15..]) == [2,5,15,22,25,35,42,45,55,62] mezcla :: Ord a => [a] -> [a] -> [a] mezcla us@(x:xs) vs@(y:ys) | x < y = x : mezcla xs vs | otherwise = y : mezcla us ys -- (esCapicua x) se verifica si x es capicúa. Por ejemplo, -- esCapicua 353 == True -- esCapicua 3553 == True -- esCapicua 3535 == False esCapicua :: Integer -> Bool esCapicua x = xs == reverse xs where xs = show x noSuma2Capicuas :: [Integer] noSuma2Capicuas = [x | x <- [0..] , null (sumas2Capicuas x)]