Sumas parciales de Juzuk
En 1939 Dov Juzuk extendió el método de Nicómaco del cálculo de los cubos. La extensión se basaba en los siguientes pasos:
- se comienza con la lista de todos los enteros positivos
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ...
- se agrupan tomando el primer elemento, los dos siguientes, los tres siguientes, etc.
[[1], [2, 3], [4, 5, 6], [7, 8, 9, 10], [11, 12, 13, 14, 15], ...
- se seleccionan los elementos en posiciones pares
[[1], [4, 5, 6], [11, 12, 13, 14, 15], ...
- se suman los elementos de cada grupo
[1, 15, 65, ...
- se calculan las sumas acumuladas
[1, 16, 81, ...
Las sumas obtenidas son las cuantas potencias de los números enteros positivos.
Definir las funciones
listasParcialesJuzuk :: [a] -> [[a]] sumasParcialesJuzuk :: [Integer] -> [Integer]
tal que
- (listasParcialesJuzuk xs) es lalista de ls listas parciales de Juzuk; es decir, la selección de los elementos en posiciones pares de la agrupación de los elementos de xs tomando el primer elemento, los dos siguientes, los tres siguientes, etc. Por ejemplo,
λ> take 4 (listasParcialesJuzuk [1..]) [[1],[4,5,6],[11,12,13,14,15],[22,23,24,25,26,27,28]] λ> take 4 (listasParcialesJuzuk [1,3..]) [[1],[7,9,11],[21,23,25,27,29],[43,45,47,49,51,53,55]]
- (sumasParcialesJuzuk xs) es la lista de las sumas acumuladas de los elementos de las listas de Juzuk generadas por xs. Por ejemplo,
take 4 (sumasParcialesJuzuk [1..]) == [1,16,81,256] take 4 (sumasParcialesJuzuk [1,3..]) == [1,28,153,496]
Comprobar con QuickChek que, para todo entero positivo n,
- el elemento de (sumasParcialesJuzuk [1..]) en la posición (n-1) es
n^4
. - el elemento de (sumasParcialesJuzuk [1,3..]) en la posición (n-1) es
n^2*(2*n^2 - 1)
. - el elemento de (sumasParcialesJuzuk [1,5..]) en la posición (n-1) es
4*n^4-3*n^2
. - el elemento de (sumasParcialesJuzuk [2,3..]) en la posición (n-1) es
n^2*(n^2+1)
.
Soluciones
import Data.List (genericIndex) import Test.QuickCheck listasParcialesJuzuk :: [a] -> [[a]] listasParcialesJuzuk = elementosEnPares . listasParciales -- (listasParciales xs) es la agrupación de los elementos de xs obtenida -- tomando el primer elemento, los dos siguientes, los tres siguientes, -- etc. Por ejemplo, -- λ> take 5 (listasParciales [1..]) -- [[1],[2,3],[4,5,6],[7,8,9,10],[11,12,13,14,15]] listasParciales :: [a] -> [[a]] listasParciales = aux 1 where aux n xs = ys : aux (n+1) zs where (ys,zs) = splitAt n xs -- (elementosEnPares xs) es la lista de los elementos de xs en -- posiciones pares. Por ejemplo, -- λ> elementosEnPares [[1],[2,3],[4,5,6],[7,8,9,10],[11,12,13,14,15]] -- [[1],[4,5,6],[11,12,13,14,15]] elementosEnPares :: [a] -> [a] elementosEnPares [] = [] elementosEnPares [x] = [x] elementosEnPares (x:_:xs) = x : elementosEnPares xs sumasParcialesJuzuk :: [Integer] -> [Integer] sumasParcialesJuzuk xs = scanl1 (+) (map sum (listasParcialesJuzuk xs)) -- La primera propiedad es prop_sumasParcialesJuzuk :: (Positive Integer) -> Bool prop_sumasParcialesJuzuk (Positive n) = sumasParcialesJuzuk [1..] `genericIndex` (n-1) == n^4 -- Su comprobación es -- λ> quickCheck prop_sumasParcialesJuzuk -- +++ OK, passed 100 tests. -- La segunda propiedad es prop_sumasParcialesJuzuk2 :: (Positive Integer) -> Bool prop_sumasParcialesJuzuk2 (Positive n) = sumasParcialesJuzuk [1,3..] `genericIndex` (n-1) == n^2*(2*n^2 - 1) -- Su comprobación es -- λ> quickCheck prop_sumasParcialesJuzuk2 -- +++ OK, passed 100 tests. -- La tercera propiedad es prop_sumasParcialesJuzuk3 :: (Positive Integer) -> Bool prop_sumasParcialesJuzuk3 (Positive n) = sumasParcialesJuzuk [1,5..] `genericIndex` (n-1) == 4*n^4-3*n^2 -- Su comprobación es -- λ> quickCheck prop_sumasParcialesJuzuk3 -- +++ OK, passed 100 tests. -- La cuarta propiedad es prop_sumasParcialesJuzuk4 :: (Positive Integer) -> Bool prop_sumasParcialesJuzuk4 (Positive n) = sumasParcialesJuzuk [2,3..] `genericIndex` (n-1) == n^2*(n^2+1) -- Su comprobación es -- λ> quickCheck prop_sumasParcialesJuzuk4 -- +++ OK, passed 100 tests.