Menu Close

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)]
Medio

4 soluciones de “Sumas de dos capicúas

  1. albcercid
    sumas2Capicuas  :: Integer -> [(Integer, Integer)]
    sumas2Capicuas x =
      [(a,x-a) | a <- takeWhile (div x 2 >=) capicuas,
                 isCap (x-a)]
      where isCap x = show x == reverse (show x)
     
    noSuma2Capicuas :: [Integer]
    noSuma2Capicuas =
      [x | x <- [0..], null (sumas2Capicuas x)]
     
    capicuas :: [Integer]
    capicuas = 0 : rRr 1
      where rRr n =  [read (show x ++ tail (reverse (show x)))
                     | x <- [10^(n-1)..10^n-1]]
                  ++ [read (show x ++ reverse (show x))
                     | x <- [10^(n-1)..10^n-1]]
                  ++ rRr (n+1)
  2. enrnarbej
    sumas2Capicuas  :: Integer -> [(Integer, Integer)]
    sumas2Capicuas n =
      [(x,y) | x <- menores,
               let y = n-x,
               y >= x,
               (read.reverse.show) y == y]
      where menores = takeWhile (<=n) capicuas
     
    noSuma2Capicuas :: [Integer]
    noSuma2Capicuas =
      filter (null.sumas2Capicuas) [1..]
  3. natmarmar2
    sumas2Capicuas :: Integer -> [(Integer,Integer)]
    sumas2Capicuas x =
      [(a,b) | a <- takeWhile (<=x) capicuas
             , let b =x-a
             , esCapicua b
             , a <= b]
     
    capicuas :: [Integer]
    capicuas = [x | x <- [0..], esCapicua x]
     
    esCapicua :: Integer -> Bool
    esCapicua x = show x == reverse (show x)
     
    noSuma2Capicuas :: [Integer]
    noSuma2Capicuas = [x | x <- [1..]
                         , null (sumas2Capicuas x)]
    • Juanjo Ortega (juaorture)

      Se puede definir “show x” como una variable local en la función “esCapicua” para mejorar la eficiencia de esta.

Escribe tu solución

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.