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