Menu Close

Sucesiones alícuotas

La sucesión alícuota de un número x es la sucesión cuyo primer término es x y cada otro término es la suma de los divisores propios del término anterior. Por ejemplo, la sucesión alícuota de 10 es [10,8,7,1,0,0,0] ya que

   la suma de los divisores propios de 10 es 5 + 2 + 1 = 8
   la suma de los divisores propios de  8 es 4 + 2 + 1 = 7
   la suma de los divisores propios de  7 es 1
   la suma de los divisores propios de  1 es 0

Definir la función

   sucAlicuota :: Integer -> [Integer]

tal que (sucAlicuota x) es la sucesión alícuota de x. Por ejemplo,

   take 6 (sucAlicuota 10)       ==  [10,8,7,1,0,0]
   take 6 (sucAlicuota 95)       ==  [95,25,6,6,6,6]
   take 6 (sucAlicuota 220)      ==  [220,284,220,284,220,284]
   sucAlicuota 1184 !! (1+10^7)  ==  1210
   sucAlicuota 276 !! 200        ==  2790456740340877466506

Soluciones

import Math.NumberTheory.ArithmeticFunctions (sigma)
 
-- 1ª definición
-- =============
 
sucAlicuota :: Integer -> [Integer]
sucAlicuota x = x : sucAlicuota (sumaDivisoresPropios x)
 
sumaDivisoresPropios :: Integer -> Integer
sumaDivisoresPropios x =
  sum [y | y <- [1..x-1], x `mod` y == 0]
 
-- 2ª definición
-- =============
 
sucAlicuota2 :: Integer -> [Integer]
sucAlicuota2 = iterate (sum . divisoresPropios)
 
divisoresPropios :: Integer -> [Integer]
divisoresPropios x = [y | y <- [1..x-1], x `mod` y == 0]
 
-- 3ª definición
-- =============
 
sucAlicuota3 :: Integer -> [Integer]
sucAlicuota3 x = aux x []
  where aux y ys | y `elem` ys = us ++ cycle zs
                 | otherwise   = aux (sumaDivisoresPropios y) (y:ys)
          where us = reverse ys
                zs = dropWhile (/=y) us
 
-- 4ª definición
-- =============
 
sucAlicuota4 :: Integer -> [Integer]
sucAlicuota4 x = x : sucAlicuota4 (sumaDivisoresPropios4 x)
 
sumaDivisoresPropios4 :: Integer -> Integer
sumaDivisoresPropios4 x =
  sigma 1 x - x
 
-- Comparación de eficiencia
-- =========================
 
--    λ> sucAlicuota 1184 !! (1+10^3)
--    1210
--    (2.02 secs, 261,081,688 bytes)
--    λ> sucAlicuota2 1184 !! (1+10^3)
--    1210
--    (2.02 secs, 245,485,568 bytes)
--    λ> sucAlicuota3 1184 !! (1+10^3)
--    1210
--    (0.02 secs, 0 bytes)
--    λ> sucAlicuota4 1184 !! (1+10^3)
--    1210
--    (0.05 secs, 0 bytes)
Medio

5 soluciones de “Sucesiones alícuotas

  1. enrnarbej
    import Data.List (nub, subsequences)
    import Data.Numbers.Primes (primeFactors)
     
    sucAlicuota :: Integer -> [Integer]
    sucAlicuota = iterate (sum . init . divisores)
     
    divisores :: Integer -> [Integer]
    divisores 0 = [0]
    divisores n = (map product . nub . subsequences . primeFactors) n
  2. albcercid
    sucAlicuota :: Integer -> [Integer]
    sucAlicuota x = x : sucAlicuota (sumdiv 1 x)
     
    sumdiv _ 0 = 0
    sumdiv a x | a > div x 2  = 0
               | mod x a == 0 = a + sumdiv (a+1) x
               | otherwise    = sumdiv (a+1) x
  3. felsuacor
    sucAlicuota :: Integer -> [Integer]
    sucAlicuota x = x : sucAlicuota (sum (factorial x))
     
    factorial :: Integer -> [Integer]
    factorial x = [n | n <- [1..x-1], x `mod` n == 0]
  4. monlagare
    sucAlicuota :: Integer -> [Integer]
    sucAlicuota x = x : sucAlicuota (sumaDivisoresPropios x)
     
    sumaDivisoresPropios :: Integer -> Integer
    sumaDivisoresPropios x = sum [y | y <- [1..x-1], mod x y == 0]
  5. marlobrip
    sucAlicuota :: Integer -> [Integer]
    sucAlicuota x = x:aux x
      where aux x = divisores x : aux (divisores x)
     
    divisores :: Integer -> Integer
    divisores 1 = 0
    divisores n = sum [ x | x <- [1..n-1], mod n x == 0]

Escribe tu solución

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