Menu Close

Números perfectos y cojonudos

Un número perfecto es un número entero positivo que es igual a la suma de sus divisores propios. Por ejemplo, el 28 es perfecto porque sus divisores propios son 1, 2, 4, 7 y 14 y 1+2+4+7+14 = 28.

Un entero positivo x es un número cojonudo si existe un n tal que n > 0, x = 2^n·(2^(n+1)-1) y 2^(n+1)-1 es primo. Por ejemplo, el 28 es cojonudo ya que para n = 2 se verifica que 2 > 0, 28 = 2^2·(2^3-1) y 2^3-1 = 7 es primo.

Definir la funciones

   esPerfecto                      :: Integer -> Bool
   esCojonudo                      :: Integer -> Bool
   equivalencia_CojonudosPerfectos :: Integer -> Bool

tales que

  • (esPerfecto x) se verifica si x es perfecto. Por ejemplo,
     esPerfecto 28  ==  True
     esPerfecto 30  ==  False
  • (esCojonudo x) se verifica si x es cojonudo. Por ejemplo,
     esCojonudo 28                   ==  True
     esCojonudo 30                   ==  False
     esCojonudo 2305843008139952128  ==  True
  • (equivalenciaCojonudosPerfectos n) se verifica si para todos los números x menores o iguales que n se tiene que x es perfecto si, y sólo si, x es cojonudo. Por ejemplo,
     equivalenciaCojonudosPerfectos 3000  ==  True

Soluciones

import Data.Numbers.Primes
import Data.List
 
-- 1ª definición de esPerfecto
-- ===========================
 
esPerfecto1 :: Integer -> Bool
esPerfecto1 x =
  sum (divisoresPropios1 x) == x
 
divisoresPropios1 :: Integer -> [Integer]
divisoresPropios1 x =
  [y | y <- [1..x-1]
     , x `mod` y == 0]
 
-- 2ª definición de esPerfecto
-- ===========================
 
esPerfecto2 :: Integer -> Bool
esPerfecto2 n = sum (divisoresPropios2 n) == n
 
divisoresPropios2 :: Integer -> [Integer]
divisoresPropios2 n =
  (delete n . nub . map product . subsequences) (primeFactors n)
 
-- Comparación de eficiencia
-- =========================
 
--    λ> esPerfecto1 33550336
--    True
--    (48.70 secs, 6,976,432,536 bytes)
--    λ> esPerfecto2 33550336
--    True
--    (0.01 secs, 0 bytes)
--    
--    λ> [x | x <- [1..10^4], esPerfecto1 x]
--    [6,28,496,8128]
--    (72.88 secs, 10,411,693,760 bytes)
--    λ> [x | x <- [1..10^4], esPerfecto2 x]
--    [6,28,496,8128]
--    (0.69 secs, 311,388,248 bytes)
 
-- 1ª definición de esCojonudo
-- ===========================
 
esCojonudo1 :: Integer -> Bool
esCojonudo1 x = pertenece x cojonudos
 
cojonudos :: [Integer]
cojonudos =
  [2^n*p | n <- [1..]
         , let p = 2^(n+1) - 1
         , isPrime p]
 
pertenece :: Integer -> [Integer] -> Bool
pertenece x ys =
  head (dropWhile (<x) ys) == x
 
-- 2ª definición de esCojonudo
-- ===========================
 
esCojonudo2 :: Integer -> Bool
esCojonudo2 n | length p /= 1  = False
              | otherwise      = head p == 2 * product d -1
    where (d,p) = partition (==2) (primeFactors n)
 
-- Comparación de eficiencia
-- =========================
 
--    λ> length [x | x <- [1..10^5], esCojonudo1 x]
--    4
--    (0.37 secs, 23,492,384 bytes)
--    λ> length [x | x <- [1..10^5], esCojonudo2 x]
--    4
--    (7.46 secs, 4,245,266,408 bytes)
 
-- Comprobación de equivalencia
-- ============================
 
equivalencia_CojonudosPerfectos :: Integer -> Bool
equivalencia_CojonudosPerfectos n =
  and [esCojonudo1 x == esPerfecto2 x | x <- [1..n]]

8 soluciones de “Números perfectos y cojonudos

  1. Juanjo Ortega (juaorture)
     
    import Data.Numbers.Primes
     
    divisoresPropios :: Integer -> [Integer]
    divisoresPropios n = [a | a <- [1..n-1]
                            , n `mod` a == 0]
     
    esPerfecto :: Integer -> Bool
    esPerfecto n = sum (divisoresPropios n) == n
     
    esCojonudo :: Integer -> Bool
    esCojonudo x = [a | a <- [1..x]
                      , isPrime (2^(a+1)-1)
                      , x == 2^a * (2^(a+1)-1)] /= []
     
    equivalenciaCojonudosPerfectos :: Integer -> Bool
    equivalenciaCojonudosPerfectos n = xs == [a | a <- xs
                                                , esCojonudo a ]
                                      where xs = [b | b <- [1..n]
                                                    , esPerfecto b]
    • Chema Cortés

      En equivalenciaCojonudosPerfectos estás comprobando que todo número perfecto es número cojonudo, pero no al revés, que todo número cojonudo sea número perfecto.

  2. Chema Cortés
    import Data.List
    import Data.Numbers.Primes
     
    esPerfecto :: Integer -> Bool
    esPerfecto n = sum (divPropios n) == n
     
    divPropios :: Integer -> [Integer]
    divPropios n = delete n . nub . map product . subsequences $ primeFactors n
     
    esCojonudo :: Integer -> Bool
    esCojonudo n | length p /= 1  = False
                 | otherwise      = head p == 2 * product d -1
        where (d,p) = partition (==2) (primeFactors n)
     
    equivalenciaCojonudosPerfectos :: Integer -> Bool
    equivalenciaCojonudosPerfectos n = all (x -> esPerfecto x == esCojonudo x) [1..n]
  3. Antonio Morales (antmorper3)
     
    import Data.Numbers.Primes
    import Data.List
     
    esPerfecto :: Integer -> Bool
    esPerfecto n = sum (factores n) == n
     
    factores :: Integer -> [Integer]
    factores n = init(map (product) (nub(subsequences(primeFactors n))))
     
    esCojonudo :: Integer -> Bool
    esCojonudo n = [k | k <- [1..n]
                      , isPrime (2^(k+1)-1)
                      , n == 2^k * (2^(k+1)-1)] /= []
     
    equivalenciaCojonudosPerfectos :: Integer -> Bool
    equivalenciaCojonudosPerfectos n = map (esPerfecto) [1..n] ==
      map (esCojonudo) [1..n]
  4. Antonio Morales (antmorper3)
     
    import Data.Numbers.Primes
    import Data.List
     
    esPerfecto :: Integer -> Bool
    esPerfecto n = sum (factores n) == n
     
    factores :: Integer -> [Integer]
    factores n = init(map (product) (nub(subsequences(primeFactors n))))
     
    esCojonudo :: Integer -> Bool
    esCojonudo n | length p /= 1  = False
                 | otherwise      = head p == 2 * product d -1
        where (d,p) = partition (==2) (primeFactors n)
     
    equivalenciaCojonudosPerfectos :: Integer -> Bool
    equivalenciaCojonudosPerfectos n = xs == [a | a <- xs, esPerfecto a] &&
      ys == [b | b <- ys , esCojonudo b]
                where xs = [x | x <- [1..n], esCojonudo x]
                      ys = [y | y <- [1..n], esPerfecto y]
  5. enrnarbej
    import Data.Numbers.Primes
    import Data.List
     
    divisores :: Integer -> [Integer]
    divisores = map (product) .nub . subsequences . primeFactors 
     
    esPerfecto :: Integer -> Bool
    esPerfecto n = sum (divisores(n)) == 2*n
     
    esCojonudo :: Integer -> Bool
    esCojonudo n = (length f2 == 1) && (all (==2) h) && (length f1 + 1 == length h)
               where
                p = partition (==2) (primeFactors n)
                f1 = fst p
                f2 = snd p
                h = primeFactors ((head f2)+1)
     
    equivalenciaCojonudosPerfectos :: Integer -> Bool
    equivalenciaCojonudosPerfectos n = all esPerfecto (filter esCojonudo [1..n])
  6. eliguivil
    import Math.NumberTheory.ArithmeticFunctions (divisors)
    import Data.Numbers.Primes (primes)
     
    esPerfecto :: Integer -> Bool
    esPerfecto k = sum (divisors k) == 2*k
     
    esCojonudo :: Integer -> Bool
    esCojonudo k
      | isPrime (2^(n+1)-1) && 2^(2*n+1)-2^n == k = True
      | otherwise                                 = False
      where n = ceiling (logBase 2 (realToFrac 0.25*(1+sqrt(1+8*(fromInteger k)))))
     
    equivalenciaCojonudosPerfectos :: Integer -> Bool
    equivalenciaCojonudosPerfectos n =
      and [esCojonudo x | x <- perfectos n, esPerfecto x] &&
      and [esPerfecto x | x <- cribaCoj n, esCojonudo x]
     
    perfectos :: Integer -> [Integer]
    perfectos n = [m | m <- [1..n], esPerfecto m]
     
    cribaCoj :: Integer -> [Integer]
    cribaCoj n = takeWhile (<= n) [2^(2*n+1)-2^n | n <- primes]
     
    -- λ> esCojonudo 2305843008139952128
    -- True
    -- (0.03 secs, 0 bytes)
    -- λ> equivalenciaCojonudosPerfectos 3000
    -- True
    -- (0.03 secs, 0 bytes)

    Referencias:

    Teorema de Euclides-Euler
    vídeo 1
    Prueba de la equivalencia cojonuda-perfecta

Escribe tu solución

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