Menu Close

Números de Dudeney

 

La semana pasada, Pepe Muñoz Santonja publicó en su blog Algo más que números el artículo Números de Dudeney en la base OEIS

Un número de Dudeney es un número entero n tal que el cubo de la suma de sus dígitos es igual a n. Por ejemplo, 512 es un número de Dudeney ya que (5+1+2)^3 = 8^3 = 512.

Se puede generalizar variando el exponente: Un número de Dudeney de orden k es un número entero n tal que la potencia k-ésima de la suma de sus dígitos es igual a n. Por ejemplo, 2401 es un número de Dudeney de orden 4 ya que (2+4+0+1)^4 = 7^4 = 2401.

Definir la función

   numerosDudeney :: Integer -> [Integer]

tal que (numerosDudeney k) es la lista de los números de Dudeney oe orden k. Por ejemplo,

   take 6 (numerosDudeney 3)  == [1,512,4913,5832,17576,19683]
   take 6 (numerosDudeney 4)  == [1,2401,234256,390625,614656,1679616]
   take 2 (numerosDudeney 20) == [1,1215766545905692880100000000000000000000]

Comprobar con QuickCheck que 19683 es el mayor número de Dudeney de orden 3.

Soluciones

import Test.QuickCheck
 
numerosDudeney :: Integer -> [Integer]
numerosDudeney k =
  [n^k | n <- [1..]
       , esDudeney k (n^k)]
 
esDudeney :: Integer -> Integer -> Bool
esDudeney k n =
  (sum (digitos n)) ^ k == n
 
digitos :: Integer -> [Integer]
digitos n = [read [d] | d <- show n]
 
-- La propiedad es
prop_Dudeney :: Integer -> Property
prop_Dudeney n =
  n > 0 ==> not (esDudeney 3 (19683 + n))
 
-- La comprobación es
--    λ> quickCheck prop_Dudeney
--    +++ OK, passed 100 tests.
Avanzado

6 soluciones de “Números de Dudeney

  1. Chema Cortés
    import Test.QuickCheck
     
    numerosDudeney :: Integer -> [Integer]
    numerosDudeney k = filter (esDudeney k) xs
      where xs = [x^k | x <- [1..]]
     
    esDudeney :: Integer -> Integer -> Bool
    esDudeney k x = x == (sum (digitos x))^k
     
    digitos :: Integer -> [Integer]
    digitos n = [read [c] | c <- show n]
     
    prop_dudeney :: (Positive Integer) -> Bool
    prop_dudeney (Positive n) = (not.esDudeney 3) (n+19683)
  2. Fran Cruz
    import Test.QuickCheck
     
    numerosDudeney :: Integer -> [Integer]
    numerosDudeney k = [m | n <- [1..], let m = n^k,
                            let x = sumaDigitos m, x^k == m]
     
    prop_maximo_Dudeney3 :: (Positive Integer) -> Bool
    prop_maximo_Dudeney3 (Positive n) = x^3 /= m
      where m = 19683 + n
            x = sumaDigitos m
     
    sumaDigitos :: Integer -> Integer
    sumaDigitos = foldr ( x y -> read [x] + y) 0 . show
  3. josejuan
    {-
     
      Existe un i tal que, para todo s >= i es
     
        Sum dígitos s^k < s
     
      el nº máximo de dígitos de s^k es
     
        s^k ~ 10^d
     
        d = k log10 s
     
      cuyo valor máximo es cuando todos son 9, por
      lo que se alcanza la cota máxima cuando
     
        9 k log10 s = s
     
      representada en la función `sOverflow`
     
    -}
     
    sOverflow k s = let k' = fromIntegral k
                        s' = fromIntegral s
                    in  9 * k' * logBase 10 s' < s'
     
    -- ahora podemos calcular todos los números sin
    -- recurrir a QuickCheck
    dun k = 1: [n | s <-takeWhile (not . sOverflow) [2..]
                  , let n = s^k
                  , s == (sum . map (toInteger . digitToInt) . show) n]
     
    {- Ejemplos:
     
    > dun 3
    [1,512,4913,5832,17576,19683]
     
    > dun 4
    [1,2401,234256,390625,614656,1679616]
     
    > mapM_ print $ dun 20
    1
    1215766545905692880100000000000000000000
    1424201691977055041360709423546231879609039601
    20864448472975628947226005981267194447042584001
     
    > mapM_ print $ dun 120
    1
    208305631093147769593077124832920398396424242736587139105600423547681633381448345957997431002341051384681406440179824973860848822669929122863069080109517208593661481936595852227827401123071804455068693490439387062950631497740127012356534717939472405042404759723585669336105702330636847342292588431606104304105400537826987381228458150816889796114773161175996672040171148993202310379336001
    5189753014425057489701348386485062139584865957477360434844367399843084988969366791646004249212100600480717775212590831764015670415686563804660475312078146716216806311907369813125444042567504621328266159703394297053600592102596692073626252142818051725113774238337691235318550041720433923148395754801224168556458842399838213009699562748685654937790642215723109778399221560208307212649496576
     
    -- el último número de dudeney para k=500 tiene 1967 dígitos
    > length $ show $ last $ dun 500
    1967
    (7.54 secs, 10,758,999,688 bytes)
     
     
    -}
  4. Juanjo Ortega (juaorture)
    import Test.QuickCheck
     
    numerosDudeney :: Integer -> [Integer]
    numerosDudeney k = [a | a <- [1..]
                          , esDudeney a k ]
     
    esDudeney :: Integer -> Integer -> Bool
    esDudeney n k = sum (digitos n) ^ k == n
     
    digitos :: Integer -> [Integer]
    digitos n | n < 10    = [n]
              | otherwise = n `mod` 10 : digitos (n `div` 10)
     
    prop_Dudeney3 :: Integer -> Property
    prop_Dudeney3 n = esDudeney n 3 ==> n <= 19683
     
    -- *Main> quickCheck prop_Dudeney3
    -- *** Gave up! Passed only 60 tests.
    • Juanjo Ortega (juaorture)
       
      prop_Dudeney :: Integer-> Property
      prop_Dudeney n = n > 1 ==> not (esDudeney (19683*n) 3)
       
      -- *Main> quickCheck prop_Dudeney
      -- +++ OK, passed 100 tests.
  5. Pingback: Los números de Dudeney | Sobre todo, Matemáticas

Los comentarios están cerrados.