jueves, 19 de octubre de 2023

Tríos de consecutivos con la misma suma

 

El día 5/09/2023 publiqué esta igualdad en Twitter (o X):

5923 es el inicio de una suma de primos consecutivos que equivalen a otra suma de cuadrados consecutivos:

5923+5927+5939=76^2+77^2+78^2

Aunque era una propiedad particular relacionada con la fecha, me interesó su generalización como forma de practicar algoritmos y por la posibilidad de crear igualdades similares con otros tipos de números.

Ideas previas

Para encontrar este tipo de igualdades se podría comenzar recorriendo las sumas de consecutivos del primer tipo y después buscar otro trío del segundo tipo que coincida en la suma con ellos. Después de una reflexión pausada quedó claro que era preferible recorrer los posibles tríos de las dos clases de forma paralela y alternada, como una persecución mutua:

Sucesiones de persecución

Podemos comenzar con los tríos más pequeños de cada clase. En el ejemplo serían s=2+3+5=10 y t=1+4+9=14, donde la variable s representa las sumas de primos y t la de cuadrados. Es claro que s<t, por lo que convendría avanzar hasta el siguiente trío de primos, 3+5+7=15. Ahora t<s, por lo que toca avanzar los cuadrados, t=4+9+16=29.

Ya se entiende el procedimiento elegido. Los siguientes pasos serían: s=5+7+11=23, s=7+11+13=31, t=9+16+25=50, s=11+13+17=41, s=13+17+19=49, s=17+19+23=59,...Le llamaremos persecución mutua, porque la suma pequeña siempre perseguirá a la mayor.

Tardaríamos en encontrar una coincidencia. La primera se produce en la siguiente igualdad:

1511+1523+1531=382+392+402

La distancia entre soluciones nos indica la conveniencia de un algoritmo para hoja de cálculo, que automatice el proceso, y es nuestro objetivo principal.

Coincidencia entre sumas

Si se consigue una coincidencia como la anterior, deberemos publicar la solución, con al menos el sumando inicial de cada trío y el valor de la suma. Avanzaremos un paso uno de los tríos coincidentes, y reanudaremos la persecución mutua.

Estructura del algoritmo

Definiciones previas

(A) Necesitaremos dos funciones que hagan avanzar, tanto los primos como los cuadrados, al próximo número del mismo tipo. Usaremos prox2 para los primos y prox1 para los cuadrados:

function prox1(n)
dim m

m=n+1
while not escuad(m):m=m+1:wend
prox1=m
end function

function prox2(n)
dim m

m=n+1
while not esprimo(m):m=m+1:wend
prox2=m
end function

Tienen la misma estructura, pero la primera usa la función escuad y la segunda esprimo. Ambas avanzan los números de uno en uno hasta llegar al siguiente cuadrado o primo.

(B) Los tríos los representaremos como un vector de tres dimensiones, sean a(3) y b(3). De esta forma, los tríos avanzaran así: a(1)=a(2), a(2)=a(3), a(3)=prox(a(3)), e igual con el vector b. Estos avances se producirán en uno u otro vector según sean las sumas, que almacenaremos en las variables s y t. 

También definiremos el tope de la búsqueda, que si es muy grande ralentizará el proceso. Usaremos la suma de los tríos para controlar el final del algoritmo.

(C) Fases del algoritmo:

         Se inician las variables
         Los tríos comienzan a avanzar con el criterio de que el que tenga menor suma avanza.
         Si coinciden las sumas, se publican los resultados y se sigue el avance alternativo.
         Se continúa hasta que la suma llega a un tope.

Esto se puede traducir a cualquier lenguaje de programación, pero aquí usamos las hojas de cálculo. Los procedimientos leecelda y escribecelda son propios del autor, pero se pueden sustituir fácilmente en la hoja de cálculo que se use.


Código en Vbasic

sub trios()

‘Se dimensionan sumas, tope y vectores de los tríos

dim a(3), b(3)
dim tope, s, t, fila

‘Se inician las variables y vectores

tope=leecelda(3,5,2)
s=0:t=0:fila=4
a(1)=prox1(0):a(2)=prox1(a(1)):a(3)=prox1(a(2)):s=a(1)+a(2)+a(3)
b(1)=prox2(0):b(2)=prox2(b(1)):b(3)=prox2(b(2)):t=b(1)+b(2)+b(3)

'Puede darse igualdad inicial

If s = t Then

'Se publican resultados

fila = fila + 1
Call escribecelda(3, 3, fila, s)
Call escribecelda(3, 4, fila, a(1))
Call escribecelda(3, 5, fila, b(1))
a(1) = a(2): a(2) = a(3): a(3) = prox1(a(3)): s = a(1) + a(2) + a(3)
End If

‘El proceso continuará hasta que la suma alcance un tope

while s<=tope and t<=tope

‘Si s<t, avanza el primer trío

 while s<t
a(1)=a(2):a(2)=a(3):a(3)=prox1(a(3)):s=a(1)+a(2)+a(3)
‘Se ha producido coincidencia

if s=t then

‘Se publican resultados

fila=fila+1
escribecelda(3,3,fila,s)
escribecelda(3,4,fila,a(1)
escribecelda(3,5,fila,b(1))
a(1)=a(2):a(2)=a(3):a(3)=prox1(a(3)):s=a(1)+a(2)+a(3)
end if

wend

‘Avanza el segundo trío

while t<s

b(1)=b(2):b(2)=b(3):b(3)=prox2(b(3)):t=b(1)+b(2)+b(3)
‘Se ha producido coincidencia

if s=t then
‘Se publican resultados

fila=fila+1
escribecelda(3,3,fila,s)
escribecelda(3,4,fila,a(1))
escribecelda(3,5,fila,b(1))
b(1)=b(2):b(2)=b(3):b(3)=prox2(b(3)):t=b(1)+b(2)+b(3)
end if

wend

wend

end sub

A pesar de su complejidad, este algoritmo es razonablemente rápido. En pocos segundos, en un equipo antiguo, nos da los primeros resultados:

 

La tercera columna, la de los primos iniciales, está publicada en https://oeis.org/A298223. Es interesante estudiar su algoritmo en PARI, porque aprovecha las propiedades algebraicas de los cuadrados. Aquí nuestro interés es usar un algoritmo general, y por eso no lo hemos aprovechado.

Otros ejemplos de comprobación

Cuadrados y libres de cuadrados

 


La suma 14, por ejemplo, proviene de 14=12+22+32=3+5+6

Primos y triangulares

 


Por ejemplo, 31 proviene de 31=7+11+13=6+10+15


Como deseábamos un algoritmo general, con estos ejemplos queda claro que funciona.

 

No hay comentarios: