-- 1ª definición de sucFractal
-- ===========================
sucFractal1 :: [Integer]
sucFractal1 =
map termino [0..]
-- (termino n) es el término n de la secuencia anterior. Por ejemplo,
-- termino 0 == 0
-- termino 1 == 0
-- map termino [0..10] == [0,0,1,0,2,1,3,0,4,2,5]
termino :: Integer -> Integer
termino 0 = 0
termino n
| even n = n `div` 2
| otherwise = termino (n `div` 2)
-- 2ª definición de sucFractal
-- ===========================
sucFractal2 :: [Integer]
sucFractal2 =
0 : 0 : mezcla [1..] (tail sucFractal2)
-- (mezcla xs ys) es la lista obtenida intercalando las listas infinitas
-- xs e ys. Por ejemplo,
-- take 10 (mezcla [0,2..] [0,-2..]) == [0,0,2,-2,4,-4,6,-6,8,-8]
mezcla :: [Integer] -> [Integer] -> [Integer]
mezcla (x:xs) (y:ys) =
x:y:mezcla xs ys
-- Comparación de eficiencia de definiciones de sucFractal
-- =======================================================
-- λ> sum (take (10^6) sucFractal1)
-- 166666169612
-- (5.56 secs, 842,863,264 bytes)
-- λ> sum (take (10^6) sucFractal2)
-- 166666169612
-- (1.81 secs, 306,262,616 bytes)
-- En lo que sigue usaremos la 2ª definición
sucFractal :: [Integer]
sucFractal = sucFractal2
-- 1ª definición de sumaSucFractal
-- ===============================
sumaSucFractal1 :: Integer -> Integer
sumaSucFractal1 n =
sum (map termino [0..n-1])
-- 2ª definición de sumaSucFractal
-- ===============================
sumaSucFractal2 :: Integer -> Integer
sumaSucFractal2 n =
sum (take (fromIntegral n) sucFractal)
-- 3ª definición de sumaSucFractal
-- ===============================
sumaSucFractal3 :: Integer -> Integer
sumaSucFractal3 0 = 0
sumaSucFractal3 1 = 0
sumaSucFractal3 n
| even n = sumaN (n `div` 2) + sumaSucFractal3 (n `div` 2)
| otherwise = sumaN ((n+1) `div` 2) + sumaSucFractal3 (n `div` 2)
where sumaN n = (n*(n-1)) `div` 2
-- Comparación de eficiencia de definiciones de sumaSucFractal
-- ===========================================================
-- λ> sumaSucFractal1 (10^6)
-- 166666169612
-- (5.25 secs, 810,622,504 bytes)
-- λ> sumaSucFractal2 (10^6)
-- 166666169612
-- (1.72 secs, 286,444,048 bytes)
-- λ> sumaSucFractal3 (10^6)
-- 166666169612
-- (0.01 secs, 0 bytes)
--
-- λ> sumaSucFractal2 (10^7)
-- 16666661685034
-- (17.49 secs, 3,021,580,920 bytes)
-- λ> sumaSucFractal3 (10^7)
-- 16666661685034
-- (0.01 secs, 0 bytes)