Hintergrund
Die 1-2-3-Tribonacci-Sequenz
Stellen Sie sich für eine Sekunde vor, Sie könnten eine Fibonacci-Sequenz erstellen, indem Sie die Standard-Iterationsformel durch Folgendes ersetzen:
Anstatt die letzten beiden zu addieren, um die nächsten zu erhalten, summieren Sie die letzten drei. Dies ist die Basis für die 1-2-3-Tribonacci-Sequenz.
Browns Kriterium
Browns Kriterium besagt, dass Sie einen beliebigen ganzzahligen Wert als Summe der Mitglieder einer Sequenz darstellen können, vorausgesetzt, dass:
Für alle
n
größer als 1,
Was dies für die Herausforderung bedeutet
Sie können jede positive ganze Zahl als eine Summe von Mitgliedern der 1-2-3-Tribonacci-Sequenz beschreiben, die sich aus den folgenden Anfangsbedingungen zusammensetzt:
Dies ist bekannt, da für jeden Wert in dieser Sequenz das Verhältnis zwischen Termen niemals größer als 2 ist (das Verhältnis ergibt einen Durchschnitt von etwa 1,839).
Wie schreibe ich in diesem numerischen Darstellungssystem?
Angenommen, Sie verwenden eine Little-Endian-Darstellung. Richten Sie die Mitglieder der Sequenz wie folgt aus:
1 2 3 6 11 20 37 68
Dann nehmen Sie Ihre Zahl, um dargestellt zu werden (für unsere Tests sagen wir es ist 63
) und finden die Werte der gegebenen 1-2-3-Tribonacci, die sich zu 63 summieren (unter Verwendung der größten Werte zuerst!) . Wenn die Zahl Teil der Summe ist, setzen Sie eine 1 darunter, andernfalls eine 0.
1 2 3 6 11 20 37 68
0 0 0 1 0 1 1 0
Sie können dies für eine beliebige Ganzzahl tun - stellen Sie einfach sicher, dass Sie zuerst die größten Werte unter Ihrer angegebenen Eingabe verwenden!
Definition (endlich)
Schreiben Sie ein Programm oder eine Funktion, die bei einer positiven Ganzzahleingabe n
(in einer beliebigen Standardbasis) zwischen 1 und dem Maximalwert Ihrer Sprache Folgendes bewirkt:
- Konvertieren Sie den Wert in die definierte numerische Darstellung von 1-2-3-Tribonacci.
- Verwenden Sie diese binäre Darstellung und lesen Sie sie als wäre sie binär. Dies bedeutet, dass die Ziffern gleich bleiben, aber was sie bedeuten, ändert sich.
- Nehmen Sie diese Binärzahl und rechnen Sie sie in die Basis der ursprünglichen Zahl um.
- Diese neue Nummer ausgeben oder zurückgeben.
Solange die Ausgabe gültig ist, müssen Sie diese Schritte jedoch nicht ausführen. Wenn Sie auf magische Weise eine Formel finden, die kürzer (und mathematisch äquivalent) ist, können Sie sie gerne verwenden.
Beispiele
Sei die Funktion f
die durch die Definition beschriebene Funktion und []
repräsentiere die durchgeführten Schritte (als Little-Endian, obwohl es keine Rolle spielen sollte) (Sie müssen diesen Prozess nicht befolgen, dies ist nur der beschriebene Prozess):
>>> f(1)
[1]
[1]
[1]
1
>>> f(5)
[5]
[0, 1, 1]
[6]
6
>>> f(63)
[63]
[0, 0, 0, 1, 0, 1, 1]
[104]
104
quelle
Antworten:
Javascript
117111 BytesVielen Dank an @theonlygusti für die Unterstützung beim Golfspielen mit 5 Bytes
Wie es funktioniert
Zunächst generiert die Funktion alle Tribonacci-Zahlen, bis sie eine finden, die größer als die Eingabe ist
Anschließend wird die Liste der Nummern in umgekehrter Reihenfolge durchsucht. Wenn eine Zahl kleiner als die Eingabe ist, addiert sie 2 ^ (Index dieser Zahl) zum Rückgabewert und reduziert die Eingabe um diese Zahl.
Schließlich gibt es das Ergebnis zurück.
Probieren Sie es online
quelle
a[++i]<x
ist mit der for-Bedingung, um ein Byte zu speichern?x>0
mitx
. Speichern Sie weitere 2 Bytes.Python 2 ,
110102 Bytes-3 Bytes dank Rod (netter Trick für boolean Gießen
i
mit in einen int+i
so die repr`+i`
works)Probieren Sie es online!
quelle
'01'[i]
mit`+i`
i
ist ein Boolescher Wert, kein Int. Bearbeiten - Ohhh+i
, ordentlich.JavaScript (ES6),
97ByteHier verwenden wir
reduce()
eine rekursive Funktion. Wir gehen davon aus, dass die Ausgabe 31-Bit ist (dies ist die größte vorzeichenlose Größe, mit der JS für bitweise Operationen ohnehin problemlos arbeiten kann).In Bezug auf die Leistung ist dies eindeutig nicht sehr effizient.
Für die Neugierigen:
F()
für N + 1reduce()
Iterationen und N-Iterationen konvergiert schnell gegen die Tribonacci-Konstante (39 1.83929). Daher kostet jedes zusätzliche Bit in der Ausgabe ungefähr doppelt so viel Zeit wie das vorherige.F()
Funktion gut 124 Millionen Mal aufgerufen.Prüfung
NB: Dies kann 1 oder 2 Sekunden dauern.
Code-Snippet anzeigen
quelle
Mathematica,
7874 BytesLinearRecurrence[{1,1,1},{1,2,3},#]
generiert eine Liste mit der Länge der Eingabe der 1-2-3 Tribonacci-Zahlen. (Das{1,1,1}
stellt die Summe der vorherigen drei Terme dar, wobei{1,2,3}
es sich um die Anfangswerte handelt.)#~NumberDecompose~
Findet dann den gierigsten Weg, um die Eingabe als Summe von Elementen der Liste zu schreiben (dies ist dieselbe Funktion, die einen Geldbetrag in Vielfache von zerlegen würde die verfügbaren Währungen, zum Beispiel). Endlich,Fold[#+##&,...]
wandelt die sich ergebende binäre Liste in eine (Basis 10) integer.Vorherige Einreichung:
Wie es häufig der Fall ist (wenn auch nicht oben), ist diese Golfversion bei Eingaben größer als 20 oder so sehr langsam, da sie (mit nicht optimierter Rekursion) eine Liste von Stämmen erzeugt, deren Länge die Eingabe ist; Das Ersetzen des Finales
#
durch eine vernünftigere BindungRound[2Log@#+1]
führt zu einer viel besseren Leistung.quelle
123Tribonacci[]
eingebautes?Haskell, 95 Bytes
Anwendungsbeispiel:
f 63
->104
. Probieren Sie es online! .So funktioniert es:
!
Baut die 1-2-3-Tribonacci-Sequenz auf. Gegeben1
,2
und3
als Startparameter nehmen wir die erstenn
Elemente der Sequenz. Dann klappen wir von der rechten Funktion ab,#
die das nächste Elemente
von subtrahiertn
und das Bit in den Rückgabewert setzt,r
wenne
es benötigt wird oder das Bit nicht gesetzt wird. Das Setzen des Bits verdoppelt sichr
und das Hinzufügen1
, das Deaktivieren des Bits verdoppelt sich nur.quelle
Jelly , 31 Bytes
Probieren Sie es online!
Ich bin mir fast sicher, dass es einen VIEL kürzeren Weg gibt, um dies in Jelly zu erreichen.
Wie?
quelle
Perl 6 ,
9391 Bytes-2 Bytes dank b2gills
Wie es funktioniert
Zunächst wird die 1-2-3-Tribonacci-Sequenz bis zum ersten Element generiert, das größer als die Eingabe ist:
Darauf aufbauend findet es die Teilmenge der Sequenz, die sich zur Eingabe addiert:
Darauf aufbauend erstellt es eine Liste von Booleschen Werten, die angeben, ob jedes Element der Sequenz Teil der Summe ist:
Und schließlich interpretiert es diese Liste der Werte True = 1, False = 0 als Basis 2 und gibt sie als Zahl (Basis 10) zurück:
quelle
*>$^n
und kürzen.sum==$n
. Auch der Raum zwischenmy
und wird nicht benötigt@f
JavaScript (ES6),
61 bis60 ByteBerechnet die 1-2-3-Tribonacci-Zahlen, bis sie die ursprüngliche Zahl erreicht haben. Wenn sich die Rekursion abwickelt, wird versucht, jede nacheinander zu subtrahieren, wobei das Ergebnis nach und nach verdoppelt wird.
Bearbeiten: 1 Byte dank @Arnauld gespeichert.
quelle
n=>(g=(x,y,z)=>(n>x&&g(y,z,x+y+z)*2)+!(n<x||![n-=x]))(1,2,3)
ein Byte speichern?n<x||
aber das![]
ist einfach genial.Batch,
151148145 BytesPort meiner JavaScript-Antwort. Bearbeiten: 3 Bytes durch Übergeben meiner Unterprogrammargumente in umgekehrter Reihenfolge und weitere 3 Bytes durch Verwenden einzelner
@
s in jeder Zeile anstelle von gespeichert@echo off
.quelle
Jelly ,
191817 BytesProbieren Sie es online!
Hintergrund
Anstatt zu versuchen, eine Ganzzahl in eine 1,2,3-Tribonacci-Basis zu konvertieren, dann von binär in eine Ganzzahl, machen wir das Gegenteil: konvertieren Sie Ganzzahlen in binär, dann von einer 1,2,3-Trionacci-Basis in eine Ganzzahl und geben Sie zurück die höchste, die der Eingabe entspricht. Dies ist leicht zu bewerkstelligen.
Wir werden den Prozess für die Eingabe 63 veranschaulichen , insbesondere den Schritt, in dem 104 getestet wird. In der Binärzahl ist 104 von der höchstwertigen bis zur niedrigstwertigen Ziffer gleich
wobei die zweite Zeile die Positionswerte dieser Ziffern darstellt.
Wir können die 1,2,3-Tribonacci-Sequenz nach rechts erweitern und dabei beobachten, dass die hinzugefügten Ziffern der gleichen rekursiven Formel entsprechen. Für drei Millionen Ziffern ergibt dies
Um nun den Wert der 1,2,3-Tribonacci-Basiszahl zu berechnen, können wir die rekursive Formel verwenden. Da jede Zahl die Summe der drei Zahlen rechts davon ist (in der obigen Tabelle), können wir die erste Ziffer entfernen und diese zu den ersten drei Ziffern des verbleibenden Arrays hinzufügen. Nach 7 Schritten, was der Anzahl der Binärziffern von 104 entspricht , sind nur noch drei Stellen übrig.
Da nun die erste und die letzte verbleibende Ziffer beide den Positionswert 0 haben , ist das Ergebnis die mittlere Ziffer, dh 63 .
Wie es funktioniert
quelle
Jelly ( Gabel ),
1716 Bytes1 Byte gespart dank @Dennis, der Golf gespielt hat, ohne es überhaupt laufen zu lassen.
Dies beruht auf einer Jelly-Gabel, bei der ich enttäuschenderweise immer noch an der Implementierung eines effizienten Frobenius-Lösungsatoms arbeite. Für diejenigen, die interessiert sind, möchte ich Mathematica Geschwindigkeit in
FrobeniusSolve
und zum Glück gibt es eine Erklärung für ihre entsprechen Methode in dem Artikel "Änderungen vornehmen und Umbauten finden: Balancing a Knapsack" von Daniel Lichtblau.Erläuterung
quelle
ḣ3S;µ¡¶3RṚdzæFṪḄ
funktionieren Ich habe Ihre Gabel nicht installiert und kann sie daher nicht testen.³
verweist auf das erste Argument.jelly.py
hatte nach dem letzten Commit noch ein paar andere Dinge drin.Gleichstrom ,
110102 BytesNun, scheint wie große Geister haben gleich denken. Anscheinend ist der Algorithmus, mit dem ich die Einschränkungen von
dc
umgehen wollte, zufällig genau der gleiche, der in der Antwort von @ LliwTelrac verwendet wurde. Interessant.Probieren Sie es online!
quelle
Python 2 , 93 Bytes
Dies ist ein Hafen von meiner Gelee-Antwort .
Probieren Sie es online!
quelle
Bash + BSD-Dienstprogramme (OS X usw.), 53 Byte
Bash + GNU-Dienstprogramme (funktioniert auch unter BSD), 59 Bytes
Die Eingabe und Ausgabe in beiden oben genannten Fällen erfolgt binär.
Probieren Sie die GNU-Version bei TIO aus. (Das mit verknüpfte Beispiel zeigt die Eingabe von 111111 (63 in binär) und die Ausgabe von 1101000 (104 in binär).)
Ich glaube nicht, dass TIO eine BSD-Option anbietet, aber wenn Sie einen Mac zur Verfügung haben, können Sie beide ausprobieren. (Das 59-Byte-Programm ist viel schneller als das 53-Byte-Programm.)
Leider
seq
kann anstelle von nicht einfach in die BSD-Lösung geworfen werdenjot
, da das Ausgabeformat fürseq
für Ausgaben über 999999 unterschiedlich ist. (Dies beginnt ein Problem für Eingaben um 32, da 32 ^ 4> 1000000.)Sie können
jot
oben mit ersetzenseq -f%.f
, damit dies mit GNU-Dienstprogrammen funktioniert, aber für die gleichen 59 Bytes können Sie die oben genannte GNU-Lösung verwenden, die viel schneller ist.quelle