En este ejercicio se considerará la serie
1 - 2 + 3 - 4 + 5 - 6 + 7 - 8 + 9 - 10 + ··· |
1 - 2 + 3 - 4 + 5 - 6 + 7 - 8 + 9 - 10 + ···
Definir las funciones
serie :: [Integer]
sumaSerie :: Integer -> Integer |
serie :: [Integer]
sumaSerie :: Integer -> Integer
tales que
- serie es lalista de los términos de la serie anterior; es decir,
take 7 serie == [1,-2,3,-4,5,-6,7] |
take 7 serie == [1,-2,3,-4,5,-6,7]
- (sumaSerie n) es la suma de los n primeros términos de la serie. Por ejemplo,
sumaSerie 5 == 3
sumaSerie 6 == -3
sumaSerie 2021 == 1011
length (show (sumaSerie (10^1000))) == 1001 |
sumaSerie 5 == 3
sumaSerie 6 == -3
sumaSerie 2021 == 1011
length (show (sumaSerie (10^1000))) == 1001
Comprobar con QuickCheck que
- la suma de la serie se puede hacer tan grande como se desee; es decir, que para todo número a existe un n tal que la suma de los n primeros términos de la serie es mayor que a;
- la suma de la serie se puede hacer tan pequeña como se desee; es decir, que para todo número a existe un n tal que la suma de los n primeros términos de la serie es menor que a.
Soluciones
import Data.List (cycle, genericTake)
import Test.QuickCheck (Property, (==>), quickCheck)
-- 1ª definición de serie
-- ======================
serie :: [Integer]
serie = [(-1)^(n-1) * n | n <- [1..]]
-- 2ª definición de serie
-- ======================
serie2 :: [Integer]
serie2 = zipWith (*) (cycle [1,-1]) [1..]
-- 3ª definición de serie
-- ======================
serie3 :: [Integer]
serie3 = zipWith ($) (cycle [id,negate]) [1..]
-- 1ª definición de sumaSerie
-- ==========================
sumaSerie :: Integer -> Integer
sumaSerie n = sum (genericTake n serie)
-- 2ª definición sumaSerie
-- =======================
-- La 2ª definición se basa en la siguiente observación
-- + Si n es par, entonces
-- 1 - 2 + 3 - 4 + 5 - 6 + ··· + (n-1) - n
-- = (1 - 2) + (3 - 4) + (5 - 6) + ··· + ((n-1) - n)
-- = -1 - 1 - 1 - ··· - 1
-- = -1 * n/2
-- + Si n es impar, entonces
-- 1 - 2 + 3 - 4 + 5 - 6 + ··· + (n-2) - (n-1) + n
-- = (1 - 2) + (3 - 4) + (5 - 6) + ··· + ((n-2) - (n-1)) + n
-- = -1 - 1 - 1 - ··· - 1 + n
-- = -1 * (n-1)/2 + n
-- = n - ((n-1)/2)
sumaSerie2 :: Integer -> Integer
sumaSerie2 n
| even n = -(n `div` 2)
| otherwise = n - ((n - 1) `div` 2)
-- 3ª definición sumaSerie
-- =======================
-- La 3ª definición se basa en la siguiente observación
-- λ> [sumaSerie n | n <- [1..20]]
-- [1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,9,-9,10,-10]
sumaSerie3 :: Integer -> Integer
sumaSerie3 n = ((-1)^(n-1)*(2*n+1)+1) `div` 4
-- Equivalencia
-- ============
-- La propiedad es
prop_sumaSerie_equiv :: Integer -> Property
prop_sumaSerie_equiv n =
n > 0 ==>
sumaSerie n == sumaSerie2 n &&
sumaSerie2 n == sumaSerie3 n
-- La comprobación es
-- λ> quickCheck prop_sumaSerie_equiv
-- +++ OK, passed 100 tests.
-- Comparación de eficiencia
-- =========================
-- La comparación es
-- λ> sumaSerie (10^6)
-- -500000
-- (3.34 secs, 5,106,633,208 bytes)
-- λ> sumaSerie2 (10^6)
-- -500000
-- (0.01 secs, 102,600 bytes)
-- λ> sumaSerie3 (10^6)
-- -500000
-- (0.02 secs, 110,976 bytes)
-- λ> sumaSerie3 (10^6)
-- -500000
-- Propiedad
-- =========
-- La propiedad es
prop_sumaSerie :: Integer -> Bool
prop_sumaSerie a =
any (> a) sumas && any (< a) sumas
where sumas = [sumaSerie2 n | n <- [1..]]
-- La comprobación es
-- λ> quickCheck prop_sumaSerie
-- +++ OK, passed 100 tests. |
import Data.List (cycle, genericTake)
import Test.QuickCheck (Property, (==>), quickCheck)
-- 1ª definición de serie
-- ======================
serie :: [Integer]
serie = [(-1)^(n-1) * n | n <- [1..]]
-- 2ª definición de serie
-- ======================
serie2 :: [Integer]
serie2 = zipWith (*) (cycle [1,-1]) [1..]
-- 3ª definición de serie
-- ======================
serie3 :: [Integer]
serie3 = zipWith ($) (cycle [id,negate]) [1..]
-- 1ª definición de sumaSerie
-- ==========================
sumaSerie :: Integer -> Integer
sumaSerie n = sum (genericTake n serie)
-- 2ª definición sumaSerie
-- =======================
-- La 2ª definición se basa en la siguiente observación
-- + Si n es par, entonces
-- 1 - 2 + 3 - 4 + 5 - 6 + ··· + (n-1) - n
-- = (1 - 2) + (3 - 4) + (5 - 6) + ··· + ((n-1) - n)
-- = -1 - 1 - 1 - ··· - 1
-- = -1 * n/2
-- + Si n es impar, entonces
-- 1 - 2 + 3 - 4 + 5 - 6 + ··· + (n-2) - (n-1) + n
-- = (1 - 2) + (3 - 4) + (5 - 6) + ··· + ((n-2) - (n-1)) + n
-- = -1 - 1 - 1 - ··· - 1 + n
-- = -1 * (n-1)/2 + n
-- = n - ((n-1)/2)
sumaSerie2 :: Integer -> Integer
sumaSerie2 n
| even n = -(n `div` 2)
| otherwise = n - ((n - 1) `div` 2)
-- 3ª definición sumaSerie
-- =======================
-- La 3ª definición se basa en la siguiente observación
-- λ> [sumaSerie n | n <- [1..20]]
-- [1,-1,2,-2,3,-3,4,-4,5,-5,6,-6,7,-7,8,-8,9,-9,10,-10]
sumaSerie3 :: Integer -> Integer
sumaSerie3 n = ((-1)^(n-1)*(2*n+1)+1) `div` 4
-- Equivalencia
-- ============
-- La propiedad es
prop_sumaSerie_equiv :: Integer -> Property
prop_sumaSerie_equiv n =
n > 0 ==>
sumaSerie n == sumaSerie2 n &&
sumaSerie2 n == sumaSerie3 n
-- La comprobación es
-- λ> quickCheck prop_sumaSerie_equiv
-- +++ OK, passed 100 tests.
-- Comparación de eficiencia
-- =========================
-- La comparación es
-- λ> sumaSerie (10^6)
-- -500000
-- (3.34 secs, 5,106,633,208 bytes)
-- λ> sumaSerie2 (10^6)
-- -500000
-- (0.01 secs, 102,600 bytes)
-- λ> sumaSerie3 (10^6)
-- -500000
-- (0.02 secs, 110,976 bytes)
-- λ> sumaSerie3 (10^6)
-- -500000
-- Propiedad
-- =========
-- La propiedad es
prop_sumaSerie :: Integer -> Bool
prop_sumaSerie a =
any (> a) sumas && any (< a) sumas
where sumas = [sumaSerie2 n | n <- [1..]]
-- La comprobación es
-- λ> quickCheck prop_sumaSerie
-- +++ OK, passed 100 tests.
4 soluciones de “La serie 1 – 2 + 3 – 4 + ···”