Mathematica, 79 Bytes
Min[2#/(d=Divisors@#~Cases~_?OddQ)+d]-2⌊(2#)^.5+.5⌋+⌈Sqrt[8#+1]~Mod~1⌉&
Erläuterung
Ich konnte nicht die Mühe machen, den Algorithmus in der Herausforderung zu implementieren, deshalb wollte ich nach einer Verknüpfung zur Lösung suchen. Obwohl ich eine gefunden habe, übertrifft sie leider nicht die Mathematica-Antwort, die den Algorithmus implementiert. Trotzdem bin ich mir sicher, dass dies noch nicht optimal ist, und es könnte andere Sprachen geben, die von diesem Ansatz oder einigen der dabei gewonnenen Erkenntnisse profitieren können.
Also behaupte ich, dass die Sequenz, die wir berechnen sollen, ist:
f (n) = 2 * ( A212652 (n) - A002024 (n)) + 1 + A023532 (n-1)
Alternativ ist f (n) = 1, wenn n eine Dreieckszahl ist, und f (n) = 2 * ( A212652 (n) - A002024 (n) + 1), andernfalls.
Im ersten Ausdruck codiert A023532 einfach diese beiden unterschiedlichen Fälle. Die beiden anderen Folgen (plus 1) sind die Differenz zwischen der größten ganzen Zahl k bei der längsten Zerlegung von n in aufeinanderfolgende ganze Zahlen (k-i + 1) + (k-i + 2) + ... + k = n und die größte ganze Zahl j, so dass 1 + 2 + ... + j <n ist .
In etwas einfacheren Worten finden wir hier die Antwort für nicht dreieckige Zahlen: Erstens finden wir die größte dreieckige Zahl T j, die kleiner als n ist . Dann ist j die vorletzte Ganzzahl, die in Schritt 1 hinzugefügt wird (da wir nach der Addition von j + 1 n überschritten haben ). Zerlegen Sie dann n in so viele (oder so kleine) aufeinanderfolgende ganze Zahlen wie möglich und nennen Sie das Maximum unter diesen Zahlen k . Das Ergebnis ist einfach 2 * (kj) . Der intuitive Grund dafür ist, dass das Maximum in der Zerlegung mit jedem zweiten Schritt um 1 wächst und wir aufhören, wenn wir erreichenk .
Wir müssen vier Dinge zeigen, um zu beweisen, dass dies funktioniert:
- f (n) = 1 für Dreieckszahlen. Dies ist trivial, weil der erste Schritt einfach alle Dreieckszahlen durchläuft. Wenn wir während dieses Vorgangs genau n drücken, sind wir fertig und es war nur ein Schritt zu berechnen.
- Bei allen anderen Nummern enden wir immer nach einem Löschschritt, niemals nach einem Einfügeschritt. Das heißt, alle anderen f (n) sind gerade.
- In jedem Einfügeschritt nach dem ersten fügen wir nur eine einzelne Zahl hinzu. Dies garantiert, dass wir eine Zerlegung einschließlich k nach kj Stufenpaaren erreichen .
- Die endgültige Zerlegung von n , die wir erhalten, ist immer die längste mögliche Zerlegung von n in aufeinanderfolgende ganze Zahlen, oder mit anderen Worten, es ist immer die Zerlegung von n mit dem niedrigsten Maximum unter den summierten Zahlen. Mit anderen Worten, die letzte Zahl, die wir zur Summe hinzufügen, ist immer A212652 (n) .
Wir haben bereits gezeigt, warum (1) wahr ist. Als nächstes beweisen wir, dass wir nicht mit einem Einfügungsschritt enden können, außer dem ersten (was bei nicht dreieckigen Zahlen nicht der Fall ist).
Angenommen, wir haben mit einem Einfügungsschritt geendet und n erreicht, nachdem der Summe ein Wert p hinzugefügt wurde . Das bedeutet, dass der Wert vor diesem Einfügungsschritt np war ( oder weniger, wenn wir mehrere Werte gleichzeitig hinzugefügt haben). Diesem Einfügeschritt ging jedoch ein Löschschritt voraus (da wir in Schritt 1 n nicht gedrückt haben konnten ). Der letzte Wert q, den wir während dieses Löschschritts entfernt haben, war aufgrund der Funktionsweise des Algorithmus notwendigerweise kleiner als p . Aber das heißt, bevor wir q entfernt haben, hatten wir n-p + q ( oder weniger ), das ist weniger als n. Aber das ist ein Widerspruch, denn wir hätten aufhören müssen, Ganzzahlen zu entfernen, wenn wir n-p + q gedrückt hätten, anstatt ein anderes q zu entfernen . Dies beweist Punkt (2) oben. Jetzt wissen wir also, dass wir immer mit einem Löschschritt enden und dass daher alle nicht dreieckigen Zahlen gerade Ausgaben haben.
Als nächstes beweisen wir (3), dass jeder Einfügeschritt nur einen Wert einfügen kann. Dies ist im Wesentlichen eine Folgerung aus (2). Wir haben gezeigt, dass wir nach dem Addieren eines Wertes nicht genau n treffen können und da der Beweis eine Ungleichung verwendet, können wir auch nicht unter n enden (da dann n-p + q immer noch kleiner als n wäre und wir nicht hätten entfernen dürfen so viele Werte überhaupt). Wenn wir also einen einzelnen Wert hinzufügen, werden wir garantiert n überschreiten, da wir durch Entfernen eines kleineren Werts unter n gesunken sind. Daher wissen wir, dass das obere Ende der Summe mit jedem zweiten Schritt um 1 wächst . Wir kennen den Anfangswert dieses oberen Endes (es ist das kleinste m, so dassT m > n ). Jetzt müssen wir nur noch dieses obere Ende herausfinden, sobald wir die Endsumme erreicht haben. Dann ist die Anzahl der Schritte einfach doppelt so groß wie die Differenz (plus 1).
Dazu beweisen wir (4), dass die Endsumme immer die Zerlegung von n in so viele ganze Zahlen wie möglich ist, oder die Zerlegung, bei der das Maximum in dieser Zerlegung minimal ist (dh es ist die frühestmögliche Zerlegung). Wir werden das im Widerspruch wieder tun (die Formulierung in diesem Teil könnte etwas strenger sein, aber ich habe bereits viel zu viel Zeit damit verbracht ...).
Angenommen, die frühestmögliche / längste mögliche Zerlegung von n ist etwas a + (a + 1) + ... (b-1) + b , a ≤ b , und der Algorithmus überspringt sie. Das bedeutet , dass zu dem Zeitpunkt, b hinzugefügt wird, ein längeres muss keinen Teil der Summe sein. Wenn a Teil der Summe s wäre , hätten wir in diesem Moment n ≤ s . Also entweder die Summe enthält nur die Werte von a bis b , die gleich n und wir stoppen (daher haben wir diese Zersetzung nicht überspringen), oder es ist zumindest ein Wert kleiner als ein in der Summe, gewinnen den Fall n <sund dieser Wert würde entfernt werden, bis wir die genaue Summe erreicht haben (die Zerlegung wurde wiederum nicht übersprungen). So würden wir davon haben , um loszuwerden , ein vor der Zugabe von b . Das heißt aber, wir müssten eine Situation erreichen, in der a die kleinste Komponente der Summe ist und die größte noch nicht b ist. Doch an diesem Punkt können wir nicht entfernen ein , weil die Summe weniger eindeutig als n (da b fehlt), so dass wir die erforderlichen Werte hinzufügen zuerst , bis wir hinzufügen b und drücken Sie n genau. Dies beweist (4).
Nehmen wir also diese Dinge zusammen: Wir wissen, dass das erste Paar von Schritten uns einen Maximalwert von A002024 (n) gibt . Wir wissen, dass der Maximalwert der endgültigen Zersetzung ist A212652 (n) ist . Und wir wissen, dass dieses Maximum in jedem Schrittpaar einmal erhöht wird. Daher ist der endgültige Ausdruck 2 * ( A212652 (n) - A002024 (n) + 1) . Diese Formel funktioniert fast für Dreieckszahlen, außer dass wir für diese nur 1 Schritt anstelle von 2 benötigen, weshalb wir das Ergebnis mit der Indikatorfunktion der Dreieckszahlen korrigieren (oder umgekehrt, je nachdem, was praktischer ist).
Zum Schluss noch was die Umsetzung betrifft. Für die erste Sequenz verwende ich die Formel MIN (ungerade d | n; n / d + (d-1) / 2) von OEIS. Es stellt sich heraus, dass ein paar Bytes gespart werden, wenn wir den Faktor 2 in diesen Ausdruck aufnehmen, um zu erhalten MIN (ungerades d | n; 2n / d + d-1) , weil dieses -1 dann mit dem +1 in meiner ersten Version aufhört von f (n), die die beiden Fälle für dreieckige und nicht dreieckige Zahlen direkt codiert. Im Code ist dies:
Min[2#/(d=Divisors@#~Cases~_?OddQ)+d]
Für die letztere Sequenz ( 1, 2, 2, 3, 3, 3, ...
) können wir eine einfache geschlossene Form verwenden:
⌊(2#)^.5+.5⌋
Und schließlich ist die inverse Indikatorfunktion der Dreieckszahlen immer dann 0, wenn 8n + 1 ein perfektes Quadrat ist. Dies kann in Mathematica ausgedrückt werden als
⌈Sqrt[8#+1]~Mod~1⌉
Es gibt viele Möglichkeiten, diese beiden letzten Sequenzen auszudrücken und einen konstanten Versatz zwischen ihnen zu verschieben. Daher bin ich mir sicher, dass dies noch keine optimale Implementierung ist, aber ich hoffe, dass dies anderen einen Ausgangspunkt bietet, um neue Ansätze in zu untersuchen ihre eigenen Sprachen.
Da ich mich um all diese Mühe gekümmert habe, ist hier eine Handlung der Sequenz bis zu n = 1000 (ich könnte auch 100 k in ein paar Sekunden berechnen, aber es zeigt keine zusätzlichen Erkenntnisse):
Es mag interessant sein, die Variationen über diese sehr geraden Linien zu untersuchen, aber ich überlasse das jemand anderem ...