Comment trouver efficacement l'élément de la séquence Digit Sum?

20

Juste par intérêt, j'ai essayé de résoudre un problème de la catégorie "récente" du projet Euler ( séquence de chiffres ). Mais je suis incapable de penser à un moyen de résoudre le problème efficacement. Le problème est le suivant (dans la séquence de questions d'origine, il y en a deux au début, mais cela ne change pas la séquence):

La séquence de somme des chiffres est 1,2,4,8,16,23,28,38,49 .... où le terme de séquence est la somme des chiffres qui la précèdent dans la séquence. Trouvez le terme de la séquence.nthdix15th

La solution naïve ne peut pas être implémentée car elle prend beaucoup de temps. J'ai essayé de réduire le problème à un cas d'exponentiation matricielle (cela prendrait de temps) mais je n'ai pas pu trouver une telle récurrence correspondant aux critères linéaires car la récurrence de cette séquence est assez particulier. On peut voir que la séquence est régie par la récurrence:O(log(dix15))

unen=unen-1+(unen-1).....(1)

où est terme de la séquence et est une fonction qui, lorsqu'elle reçoit un nombre naturel en entrée, renvoie la somme des chiffres du nombre (par exemple ). Ma deuxième approche a été d'essayer de trouver un motif dans la séquence. On peut voir que les premiers termes de la séquence peuvent être écrits commen t h dunennth(786)=21

   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 ) ) ) )

À partir du modèle ci-dessus, il devient que le terme de la séquence peut être généré par la méthode suivante:nth

  1. Écrivez avec un symbole d'addition entre eux. 12n-1 1
  2. En laissant le premier , appliquez ensuite la fonction sur les termes suivants puis sur les termes suivants, puis sur les termes suivants et ainsi de suite.d 2 0 2 1 2 21202122
  3. Ensuite, appliquez récursivement la méthode ci-dessus sur les arguments de chaque fonction appliquée.

par exemple si n = 3 nous effectuons les manipulations suivantes:

    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 ) ) )

Par programmation dynamique, je peux générer le terme en utilisant la méthode ci-dessus dans le temps , ce qui n'est pas mieux que la solution naïve.nthO(log(2dix15))

EDIT 1
Une autre chose qui peut être observée est que . Par exemple, . Mais je ne peux pas utiliser ce point. J'ai de nouveau essayé de trouver une relation de récurrence linéaire (pour l'exponentiation matricielle), mais je n'arrive pas à la trouver.(unen)=(2n-1)(une6)=(23)=(32)=5

EDIT 2

Voici le graphique lorsque la séquence est tracée pour une plage plus petite (les premiers termes de la séquence sont tracés). dix6entrez la description de l'image ici

PS: Je sais qu'il n'est pas conseillé de demander des solutions au Project Euler. Mais je veux juste une nouvelle direction ou un indice, car je tourne en rond depuis quelques jours. Si cela est également inacceptable, je peux supprimer la question si elle est suggérée.

sashas
la source
1
J'ai l'impression que You are given a106 = 31054319.dans le problème Euler d'origine, c'est un indice.
Filip Haglund
@FilipHaglund ce n'est pas un indice. Comme par la force brute seule, je peux facilement calculer cette valeur. C'est juste pour vérifier votre approche.
sashas
3
Également sur OEIS: oeis.org/A004207 .
Yuval Filmus
@EvilJS pourrait oui. J'ai tracé le graphique jusqu'à ce qu'il augmente progressivement en zigzag. Pourriez-vous élaborer votre dernier point "" les modèles de mise en cache .. ".
sashas
Étant donné que des motifs intéressants apparaissent mod 9, quelque chose d'intéressant se produit-il si nous regardons la séquence mod 11 ou mod 99? La valeur mod 11 peut être dérivée de la somme des chiffres indexés impairs et de la somme des chiffres indexés pairs. La valeur mod 99 peut être dérivée de la somme des paires de chiffres adjacents.
DW

Réponses:

4

Votre séquence est décrite dans oeis.org/A004207 sous forme de somme de chiffres. Il y a quelques bons points comme la séquence que le mod 9 a un motif répétitif , il partage des racines numériques avec oeis.org/A065075 et oeis.org/A001370 . Si ces propriétés sont utiles, c'est un problème ouvert (car il n'y a pas d'équation de forme fermée pour le nombre n - t h ).(1,2,4,8,7,5)nth

Il y a quelques propriétés de cette séquence qui méritent d'être mentionnées:
Lorsque vous calculez nombre, vous devez stocker uniquement le compteur (pour savoir de quel nombre il s'agit) et le nombre lui-même. Pour redémarrer, il n'y a rien de plus nécessaire, car le numéro suivant est le numéro actuel + la somme de ses chiffres.nth

En prenant quelques mesures pour garantir la vitesse au début, il est bon de mettre les nombres dans le tableau, en évitant les calculs naïfs de mod et de div, qui sont chers. Cela donne une accélération constante, mais en regardant parfois, cela compte.

À partir du point de départ, vous pouvez calculer le suivant et le suivant, et cela fonctionne jusqu'à un certain point, ce point est le nombre de changements de chiffres.
Plus important encore, les modèles changent avec l'augmentation du nombre.
Les sommes des chiffres sont petites par rapport aux nombres eux-mêmes, donc seule la partie du nombre changera dans la plupart des opérations.
Alors, que pouvons-nous vraiment mettre en cache?

Nous savons qu'avec deux nombres avec la même somme de chiffres, l'addition pour obtenir le numéro suivant sera la même. Et le prochain?

sasha

Alerte spoiler, ci-dessous est un modèle de cache assez explicite

Cela dépend de conditions supplémentaires, comme les nombres qui ne changent pas pendant la course , je l'appellerai shift , montant de départ comme start .

10009100nth

100
1001

10



1,2,4,8

11012183054065176077198059041003



100,1000,10000,100000,1000000...
100

Mal
la source
4

Puisque vous avez demandé "une nouvelle direction ou un indice" et que je ne connais pas la réponse, je vais laisser cela ici, j'espère que c'est utile. Quelques idées:

Il est logique qu'il y ait un modèle mod 9, car

k>1,kZdixk1mod9

Ce que vous pouvez prouver par induction.

Cela signifie que tous les nombres sont congruents à la somme de leurs chiffres mod 9.

unen=(unen)mod9

unen=unen-1+(unen-1)=2(unen-1)mod9

Si nous continuons à étendre cette récurrence, nous obtenons

unen=2nmod9

Ce qui explique le mod mod 9.

unen=9k+2n

Voici un code moins que général:

import matplotlib.pyplot as plt
import numpy as np

#sum digits of n
def sum_digits(n):
    s = 0
    while n:
        s += n % 10
        n //= 10
    return s

#get the sequence to n digits
def calculate(n):
    retval = [1]
    for i in range(n):
        retval.append(retval[-1] + sum_digits(retval[-1]))
    return retval;

#empirically confirm that a_n = 2^n mod 9
def confirmPow2(a):
    count = 0
    for i in a[:10000]:
        if((i%9) != (2**count % 9)):
            print "false"
        count = count + 1

#find gaps divisible by 9 in a subset of a
def find9Gaps(a):
    count = 0
    S = []
    for i in a[:10000]:
         S.append(((2**count ) - i)/9)
         count = count + 1
    return S

#repeatedly sum the digits until they're less than 9...
#gives some interesting patterns
def repeatedDigitSum():
    for i in range(1000, 1100):
         print "=========for ",i
         while i > 9:
                 i = sum_digits(i)
                 print i 


a = calculate(10**6)
b = find9Gaps(a)
plt.plot(range(len(b[:100])), b[:100])
plt.show()

L'intrigue (pour les 100 premiers) semble exponentielle, mais je ne pense pas qu'elle soit parfaite.

tracer pour les lacunes

Voici la sortie de

>>> plt.plot(range(len(b[5:60])), np.log2(np.array(b[5:60])))
>>> plt.show()

tracé logarithmique des lacunes

La dernière chose que j'ai est qu'il semble que si vous additionnez les chiffres d'un nombre, puis additionnez les chiffres du nombre résultant, et répétez cela, vous obtenez finalement ce nombre mod 9.

Est logique étant donné le fait ci-dessus sur les pouvoirs de 10 mod 9.

n(n)((n))mod9

Cela donne cependant une séquence de chiffres intéressante.

Edit: Apparemment, cela s'appelle une "racine numérique".

quietContest
la source
1
Il a été en quelque sorte commenté au moins trois fois. De plus, lorsque vous faites un tracé qui vous semble exponentiel, vous devriez peut-être utiliser un logarithme, en informer sur l'axe de l'échelle? Si vous traçiez des termes lisibles de 10 ^ 16, je serais vraiment impressionné.
Evil
Qu'est-ce qui a été commenté 3 fois? Les gens disaient qu'il y avait un "pattern mod 9" mais j'avais l'impression que ce n'était pas clair. Je viens d'explorer et de commenter ce que j'avais, car je ne pense pas pouvoir continuer à travailler là-dessus. Encore une fois, je n'ai pas de solution, mais la question n'en demandait pas.
quietContest
Ajout d'un tracé de journal par suggestion EvilJS, ne peut pas tracer plus grand car les pauses engourdies et je n'ai vraiment pas le temps de continuer à résoudre ce problème
quietContest