jueves, 18 de mayo de 2017

Sumas anagramáticas


En mi cuenta de Twitter, @connumeros, publiqué el 6/4/17 la siguiente identidad, que mi hijo Juan Luis, @juanlroldan, calificó de anagramática:

6417=4671+1746

En ella los dos sumandos poseen los mismos dígitos que el resultado. Esto está ya estudiado y publicado en http://oeis.org/A203024:

Numbers a = b + c where a, b, and c contain the same decimal digits.

0, 954, 2961, 4932, 5013, 5022, 5031, 5238, 5823, 6147, 6417, 7614, 7641, 8235, 8523, 9045, 9108, 9180, 9324, 9504, 9540, 9594, 9612, 9684, 9774, 9864, 9954, 20961, 21150, 21501, 24831, 24921, 25011, 26901, 27810, 28107, 28314, 29016, 29214, 29610, 29691, 29961

Lo que nos interesa aquí es la forma de conseguirlo con hoja de cálculo. No esperéis, por tanto, teoría matemática. Quienes no disfrutéis con la programación podéis dejar de leer esta entrada.

¿Qué necesitamos para reproducir y ampliar esta lista?

Si nos inspiramos en el código PARI de Charles R Greathouse IV incluido en la página citada, la estrategia podría ser la siguiente:

1) Para cada número dado, intentamos construir el más pequeño posible con sus mismos dígitos. Por ejemplo, para 36621 deberíamos poder construir 12366 de forma automática. Llamaremos digiordenado a la función que consiga esto. Así digiordenado(36621)=12366

Con ello logramos dos cosas: conseguir el sumando menor posible y tener un elemento de comparación anagramático. Si dos números coinciden en sus valores mediante digiordenado, es que son anagrama uno de otro.

2) Una vez obtenido el conjunto ordenado de dígitos, bastará comenzar a probar el primer sumando y comprobar si los tres, total y dos sumandos, son anagramáticos.

Función DIGIORDENADO

Para construir la función citada sobre un número N deberemos

* Extraer los dígitos de la cadena N
* Ordenarlos
* Reconstruir de nuevo un número D, que será el valor de digiordenado(N).

Extracción de cifras

Existen varios métodos para extraer cifras de un número N expresado en el sistema de numeración decimal (o en otro cualquiera cambiando 10 por la base). Elegimos el de truncar los cocientes de N entre 10r y 10r+1, este último multiplicado por 10. Por ejemplo, para extraer el 5 del número 34521 deberíamos calcular:

Int(34521/100)-10*Int(34521/1000) = 345 – 10*34 = 345-340 = 5

También podíamos haber convertido N en una cadena y después extraer los caracteres de esa cadena. Así se efectúa en PARI, pero nos ha parecido mejor no acudir a cadenas.

En el listado de más abajo puedes estudiar su aplicación a nuestro problema.

Ordenación

Vamos a trabajar con pocos dígitos, por lo que el método de ordenación elegido no es relevante. Nos hemos decidido por el de “burbuja”, que es bastante comprensible. Puedes consultar

https://es.wikipedia.org/wiki/Ordenamiento_de_burbuja

Reconstrucción

Para reconstruir el número de nuevo multiplicamos y sumamos, en lugar de las operaciones de  dividir y restar de la extracción. Por ejemplo, para reconstruir las cifras 2, 3, 7 calcularíamos:

0*10+2=2
2*10+3=23
23*10+7=237

Aunque es un proceso sencillo, no es trivial, por lo que merece la pena que lo estudies.

Estas tres técnicas las tienes integradas en la función digiordenado:

Public Function digiordenado(n)
'Aplicable solo a números naturales de al menos dos cifras

Dim l, i, j
Dim c
Dim ci(10)

‘Calcula el número de cifras
l =  Int(Log(n) / Log(10) + 1)
'Extrae las cifras y las deposita en la matriz ci(i)
For i = 1 To l
c = 10 ^ (i - 1)
ci(i) = Int(n / c) - 10 * Int(n / c / 10)
Next i
'Ordena las cifras por el método de la burbuja
For i = 1 To l
For j = 1 To l - 1
If ci(j) > ci(j + 1) Then c = ci(j): ci(j) = ci(j + 1): ci(j + 1) = c
Next j
Next i
'Acumula de nuevo las cifras para obtener digiordenado
c = 0
For i = 1 To l
c = c * 10 + ci(i)
Next i
digiordenado = c
End Function

Suma anagramática

Ya sabemos construir un número con los dígitos ordenados de otro. Podemos retroceder a nuestra cuestión primera, que son las sumas del tipo

6417=4671+1746

Para cada número, obtenemos su “digiordenado”, que en este caso sería 1467, primer valor a probar como primer sumando, hasta llegar a 6417/2. Para cada sumando S comprobamos si coincide en dígitos con el número total N, mediante la igualdad digiordenado(S)=digiordenado(N). En caso afirmativo repetimos la comprobación con N-S. Si los tres coinciden en sus dígitos, hemos encontrado una suma anagramática.

A continuación lo presentamos en forma de función. Le daremos como tipo de variable el de texto, para que así el resultado sea “NO” en el caso de no admitir la descomposición y la concatenación de los sumandos si existe una descomposición de ese tipo. En el ejemplo resultaría “ 4671 1746”

Function anagram$(n) ‘Función tipo texto
Dim a, b, c
Dim anag$

anag = "NO" ‘En principio no se espera un resultado positivo
a = digiordenado(n) ‘se busca el menor número con los dígitos dados
b = a
While b <= n / 2 And anag = "NO" ‘b recorre desde a hasta n/2
c = n – b
‘Prueba de identidad de dígitos
If digiordenado(b) = a And digiordenado(c) = a Then anag = Str$(b) + Str$(c)
‘En caso positivo se concatenan los sumandos
b = b + 1
Wend
anagram = anag
End Function

Podemos aplicar este test a varios números:



Comprobamos que los que figuran en la lista de los primeros párrafos dan como resultado los dos sumandos y los que no están devuelven un “NO”.

Búsqueda de sumas anagramáticas

Con las funciones presentadas podemos, mediante un bucle FOR-NEXT, encontrar todas las incluidas en un intervalo de números dado. Como ya están publicados en http://oeis.org/A203024 los primeros casos hasta 29961=12969+16992, podíamos intentar encontrar los siguientes, que resultan ser 30168=13860+16308 y 30186=13806+16380, y así podíamos seguir. El proceso es muy lento, y habrá que dejar al ordenador trabajando solo.

Búsqueda de sumandos anagramáticos

Podíamos rebajar las exigencias, y en lugar de buscar la identidad de dígitos entre suma y sumandos, prescindir del total y buscar sólo la igualdad entre sumandos. En este caso resultarían muchos más números. Deberemos exigir, para eliminar soluciones triviales, que los sumandos sean distintos. También hay que tener en cuenta los que comienzan por un cero, que no suele aparecer en el resultado, a los que también eliminaremos. Con estas condiciones, los primeros números de este tipo son: 303=102+201, 310=119+191, 321=129+192, 330=120+ 210,...

Es lógico pensar en otra posibilidad, y es que los dígitos del total coincidan con un sumando al menos. Si prescindimos de ceros iniciales, los primeros casos resultantes son: 31=13+18, 41= 14+27, 51=15+36,…No parecen tener interés.

No hay comentarios: