Solo por interés, traté de resolver un problema de la categoría "Reciente" del Proyecto Euler ( secuencia de suma de dígitos ). Pero no puedo pensar en una forma de resolver el problema de manera eficiente. El problema es el siguiente (en la secuencia de preguntas original hay dos al principio, pero no cambia la secuencia):
La secuencia de suma de dígitos es 1,2,4,8,16,23,28,38,49 .... donde el término de secuencia es la suma de dígitos que la preceden en la secuencia. Encuentre el término de la secuencia.
La solución ingenua no se puede implementar porque lleva mucho tiempo. Traté de reducir el problema a un caso de exponenciación de la matriz (que tomaría una cantidad de tiempo ) pero no pude encontrar una recurrencia que se ajustara a los criterios lineales, ya que la recurrencia para esta secuencia es bastante peculiar Se puede ver que la secuencia se rige por la recurrencia:
donde es término de la secuencia es una función que, cuando se le da un número natural como entrada, devuelve la suma de dígitos del número (p. ej. ). Mi segundo enfoque fue tratar de encontrar algún patrón en la secuencia. Se puede ver que los primeros términos de la secuencia se pueden escribir como
a_1 = 1
a_2 = 1 + d( 1 )
a_3 = 1 + d( 1 ) + d( 1 + d( 1 ) )
a_4 = 1 + d( 1 ) + d( 1 + d( 1 ) ) + d( 1 + d( 1 ) + d( 1 + d( 1 ) ) )
a_5 = 1 + d( 1 ) + d( 1 + d( 1 ) ) + d( 1 + d( 1 ) + d( 1 + d( 1 ) ) ) + d( 1 + d(
1 ) + d( 1 + d( 1 ) ) + d( 1 + d( 1 ) + d( 1 + d( 1 ) ) ) )
A partir del patrón anterior, se convierte en que el término de la secuencia se puede generar mediante el siguiente método:
- Escriba 1 's con el símbolo de suma entre ellos.
- Dejando el primer , luego aplique la función en los próximos términos, luego en los siguientes términos, luego en los siguientes términos y así sucesivamente.
- Luego aplique el método anterior de forma recursiva en los argumentos de cada función aplicada.
por ejemplo si n = 3 realizamos las siguientes manipulaciones:
1 + 1 + 1 + 1 + 1 + 1 + 1 + 1
1 + d( 1 ) + d( 1 + 1 ) + d( 1 + 1 + 1 + 1 )
1 + d( 1 ) + d( 1 + d(1) ) + d( 1 + d( 1 ) + d( 1 +d( 1 ) ) )
Mediante la programación dinámica puedo generar el término usando el método anterior en el tiempo , que de nuevo no es mejor que la solución ingenua.
EDITAR 1
Otra cosa que se puede observar es que . Por ejemplo . Pero no puedo hacer uso de este punto. Intenté nuevamente encontrar una relación de recurrencia lineal (para la exponenciación de la matriz), pero no puedo encontrarla.
EDITAR 2
A continuación se muestra el gráfico cuando se traza la secuencia para un rango menor (se trazan los primeros términos de la secuencia).
PD: Sé que no es aconsejable pedir soluciones al Proyecto Euler. Pero solo quiero una nueva dirección o una pista, ya que me he estado moviendo en círculos durante los últimos días. Si eso también es inaceptable, puedo eliminar la pregunta si se sugiere.
fuente
You are given a106 = 31054319.
en el problema original de Euler es una pista.Respuestas:
Su secuencia se describe en oeis.org/A004207 como suma de dígitos. Hay algunos puntos buenos como que la secuencia mod 9 tiene un patrón repetitivo , comparte raíces digitales con oeis.org/A065075 y oeis.org/A001370 . Si esas propiedades son útiles es un problema abierto (porque no hay una ecuación de forma cerrada para número).( 1 , 2 , 4 , 8 , 7 , 5 )∞ n - t h
Hay algunas propiedades de esta secuencia que vale la pena mencionar:norte- t h
cuando calcula número, solo necesita almacenar el contador (para saber qué número era) y el número en sí. Para reiniciar no hay nada más necesario, ya que el siguiente número es el número actual + suma de sus dígitos.
Al tomar algunos pasos para garantizar la velocidad al principio, es bueno poner los números en la matriz, evitando cálculos ingenuos de mod y div, que son caros. Esto da aceleración por constante, pero mirando a veces sí importa.
Desde el punto de partida puede calcular el siguiente, y el siguiente, y funciona hasta cierto punto, este mismo punto es el cambio de número de dígitos.
Lo que es más importante, los patrones están cambiando con el aumento de los números.
Las sumas de dígitos son pequeñas en comparación con los números en sí, por lo que solo la parte del número cambiará en la mayoría de las operaciones.
Entonces, ¿qué podemos realmente almacenar en caché?
Sabemos que con dos números con la misma suma de dígitos, la suma para obtener el siguiente número será la misma. ¿Qué hay del próximo?
Sasha
Alerta de spoiler, a continuación se muestra un patrón de caché bastante explícito
Depende de condiciones adicionales, como los números que no cambian en la ejecución , lo llamaré turno , cantidad inicial como inicio .
Tomando una carrera arbitraria , como , y comenzando de 0 a 9 , podemos almacenar en caché cada patrón desde el punto de partida hasta 100 , contar el número de elementos (para saber cómo lidiar con el contador, que es necesario para dar algo de n - t h número), y memorizarlo.100 0 0 9 9 100 n - t h
Okay. Hasta ahora, cualquier inicio está cubierto, ¿qué cambia más allá de ? Desafortunadamente, estos patrones dejan de funcionar, porque si intenta desde 100 haciendo que el inicio sea igual a 1 , el siguiente número se calcula perfectamente, pero el segundo se rompe.100
100 1
Aquí tenemos que cubrir shift set en y empezar a 0 . También significa calcular tablas para diferentes turnos .1 0 0
¿Realmente necesitamos calcularlos todos ? No, realmente no.1 , 2 , 4 , 8
Parte de las tablas es solo otro elemento inicial más.
Por ejemplo, a partir de da la misma secuencia desplazada. Entonces, ¿necesitamos calcular un caché más largo? No, lo calculamos para cambiar el cambio y recoger otra ejecución , por lo que ahorrará mucha memoria.
Ahora, cuando la tabla está cubierta, comenzamos desde la configuración inicial, seleccionamos la suma de la tabla, agregamos el contador y vemos que: desde llegamos a 101 , actualizamos las variables y saltamos a 218 , repitiendo los pasos 305 -> 406 -> 517 -> 607 -> 719 -> 805 -> 904 -> 1003 . Okay. ¿Ahora que?1 101 218 305 406 517 607 719 805 904 1003
Podemos continuar hasta que el turno sea más alto de lo calculado.100 , 1000 , 10000 , 100000 , 1000000 ...
100
Yendo más allá, podríamos construir más carreras sobre la marcha, calcular previamente carreras más grandes u observar otros patrones (como si pudiéramos reutilizar parcialmente las tablas ya calculadas).
Eche un vistazo a diferentes turnos como todos dan la misma ejecución siendo el mismo entorno para sumas de dígitos, por lo tanto, podemos usar las mismas tablas. Hacer tablas más grandes que 100 elementos acelera aún más el proceso, haciendo saltos más grandes a la vez.
fuente
Dado que solicitó "una nueva dirección o una pista" y no sé la respuesta, lo dejaré aquí, espero que sea útil. algunas ideas:
Tiene sentido que haya un patrón mod 9, ya que
Lo que puedes probar por inducción.
Esto significa que todos los números son congruentes con la suma de sus dígitos mod 9.
Si seguimos expandiendo esta recurrencia obtenemos
Lo que explica el patrón mod 9.
Aquí hay un código menos que general:
La trama (para los primeros 100) parece exponencial, pero no creo que sea perfecta.
Aquí está la salida de
Lo último que tengo es que parece que si sumas los dígitos de un número, y luego sumas los dígitos del número resultante, y repites esto, eventualmente obtienes ese número mod 9.
Tiene sentido dado el hecho anterior sobre las potencias de 10 mod 9.
Sin embargo, da una secuencia interesante de números.
Editar: Aparentemente esto se llama una "raíz digital".
fuente