Nur aus Interesse habe ich versucht, ein Problem aus der Kategorie "Recent" von Project Euler ( Digit Sum Sequence ) zu lösen . Ich kann mir aber keinen Weg ausdenken, um das Problem effizient zu lösen. Das Problem ist wie folgt (in der ursprünglichen Fragensequenz sind am Anfang zwei vorhanden, die Reihenfolge wird jedoch nicht geändert):
Die Ziffer Summenfolge ist 1,2,4,8,16,23,28,38,49 .... wo die Laufzeit der Summe der Sequenz ist Stellen in der Sequenz vorangeht. Finden Sie den Term der Sequenz.
Die naive Lösung kann nicht implementiert werden, da dies viel Zeit in Anspruch nimmt. Ich habe versucht , das Problem zu einem Fall von Matrix Exponentiation zu reduzieren (das wäre nimmt Menge an Zeit), konnte aber nicht mit einer solchen Wiederholung Einpassen der linearen Kriterien als Rezidiv für diese Sequenz ganz kommen ist eigenartig. Es ist ersichtlich, dass die Reihenfolge durch die Wiederholung bestimmt wird:
wobei ist Term der Folge und ist eine Funktion , die , wenn eine natürliche Zahl als Eingabe kehrt Summe der Ziffern der Zahl (zB gegeben. ). Mein zweiter Ansatz bestand darin, ein Muster in der Sequenz zu finden. Es ist ersichtlich, dass die ersten Begriffe der Sequenz als geschrieben werden können
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 ) ) ) )
Aus dem Muster darüber erlangt , dass Laufzeit der Sequenz kann durch das folgende Verfahren erzeugt werden:
- Schreiben Sie mit einem Additionssymbol dazwischen.
- Verlassen Sie die erste und wenden Sie dann die Funktion d auf die nächsten 2 0 Terme an, dann auf die nächsten 2 1 Terme, dann auf die nächsten 2 2 Terme und so weiter.
- Wenden Sie dann die obige Methode rekursiv auf Argumente jeder angewendeten Funktion an.
Wenn beispielsweise n = 3 ist, führen wir die folgenden Manipulationen durch:
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 ) ) )
Durch die dynamische Programmierung kann ich die Erzeugung Laufzeit unter Verwendung des obigen Verfahrens in der Zeit O ( l o g ( 2 10 15 ) ) , was wiederum nicht besser als die naive Lösung.
BEARBEITEN 1
Eine andere Sache, die beobachtet werden kann, ist, dass . Zum Beispiel ist d ( a 6 ) = d ( 23 ) = d ( 32 ) = 5 . Aber ich kann diesen Punkt nicht nutzen. Ich habe erneut versucht, eine lineare Wiederholungsrelation zu finden (für die Matrixexponentiation), aber ich kann sie nicht finden.
BEARBEITEN 2
Es folgt die Grafik, wenn die Sequenz für einen kleineren Bereich aufgezeichnet wird (die ersten Terme der Sequenz werden aufgezeichnet).
PS: Ich weiß, dass es nicht ratsam ist, Lösungen von Project Euler anzufordern. Aber ich möchte nur eine neue Richtung oder einen Hinweis, da ich mich seit ein paar Tagen im Kreis bewege. Wenn das auch nicht akzeptabel ist, kann ich die Frage entfernen, wenn sie vorgeschlagen wird.
quelle
You are given a106 = 31054319.
in der ursprünglichen Euler-Problematik ein Hinweis.Antworten:
Ihre Sequenz wird in oeis.org/A004207 als Ziffernsumme beschrieben. Es gibt einige gute Punkte ähnliche Sequenz mod 9 hat sich wiederholendes Muster , teilt es digital Wurzeln mit oeis.org/A065075 und oeis.org/A001370 . Ob diese Eigenschaften nützlich sind, ist ein offenes Problem (da es keine geschlossene Formgleichung für n - t h gibt ).(1,2,4,8,7,5)∞ n−th
Es gibt einige Eigenschaften dieser Sequenz erwähnenswert:n−th
Wenn Sie berechnen Nummer, die Sie brauchen nur zu speichern Zähler (zu wissen , welche numer es war) und die Zahl selbst. Zum Neustart ist nichts mehr erforderlich, da die nächste Nummer die aktuelle Nummer + die Summe der Ziffern ist.
Wenn Sie zunächst ein paar Schritte unternehmen, um die Geschwindigkeit zu gewährleisten, sollten Sie die Zahlen in ein Array einfügen, um die naiven Mod- und Div-Berechnungen zu vermeiden, die teuer sind. Dies führt zu einer konstanten Beschleunigung, aber manchmal spielt es eine Rolle.
Vom Startpunkt aus können Sie den nächsten und den nächsten Punkt berechnen. Bis zu einem gewissen Punkt ist genau dieser Punkt die Änderung der Stellenzahl.
Was wichtiger ist, ändern sich die Muster mit zunehmender Anzahl.
Ziffernsummen sind im Vergleich zu Zahlen selbst klein, sodass sich bei den meisten Operationen nur der Teil der Zahl ändert.
Was können wir also wirklich zwischenspeichern?
Wir wissen, dass bei zwei Zahlen mit derselben Ziffernsumme die Addition zur nächsten Zahl dieselbe ist. Was ist mit dem nächsten?
Sasha
Der Spoiler-Alarm unten ist ein ziemlich explizites Cache-Muster
Es hängt von zusätzlichen Bedingungen ab, wie die Zahlen, die sich im Lauf nicht ändern , ich werde es Verschiebung nennen , Startbetrag als Start .
quelle
Da Sie nach "einer neuen Richtung oder einem Hinweis" gefragt haben und ich die Antwort nicht kenne, lasse ich dies hier, ich hoffe, es ist hilfreich. einige Ideen:
Sinnvollerweise gäbe es ein Pattern Mod 9, da
Was Sie durch Induktion beweisen können.
Dies bedeutet, dass alle Zahlen zur Summe ihrer Ziffern mod 9 kongruent sind.
Wenn wir diese Wiederholung weiter ausbauen, erhalten wir
Welches erklärt das Muster mod 9.
Hier ist etwas weniger als allgemeiner Code:
Die Handlung (für die ersten 100) sieht exponentiell aus, aber ich denke nicht, dass sie perfekt ist.
Hier ist die Ausgabe von
Das Letzte, was ich habe, ist, dass es den Anschein hat, als ob Sie, wenn Sie die Ziffern einer Zahl summieren und dann die Ziffern der resultierenden Zahl summieren und dies wiederholen, schließlich diese Zahl Mod 9 erhalten.
Sinnvoll angesichts der obigen Tatsache über Potenzen von 10 mod 9.
Es gibt jedoch eine interessante Folge von Zahlen.
Edit: Anscheinend wird dies eine "digitale Wurzel" genannt.
quelle