Der Satz von Zeckendorf zeigt, dass jede positive ganze Zahl eindeutig als Summe nicht benachbarter Fibonacci-Zahlen dargestellt werden kann. Bei dieser Herausforderung müssen Sie die Summe zweier Zahlen in der Zeckendorfer Darstellung berechnen.
Sei F n die n- te Fibonacci-Zahl, wobei
F 1 = 1,
F 2 = 2 und
für alle k > 2 ist F k = F k - 1 + F k - 2 .
Die Zeckendorf-Darstellung Z ( n ) einer nicht negativen ganzen Zahl n ist eine Menge positiver ganzer Zahlen, so dass
n = Σ i ∈ Z ( n ) F i und
∀ i ∈ Z ( n ) i + 1 ∉ Z ( n ).
(in prosa: Die Zeckendorf-Darstellung einer Zahl n ist eine Menge positiver Ganzzahlen, so dass sich die Fibonacci-Zahlen für diese Indizes zu n summieren und keine zwei benachbarten Ganzzahlen Teil dieser Menge sind)
Insbesondere die Darstellung von Zeckendorf ist einzigartig. Hier einige Beispiele für Zeckendorf-Darstellungen:
Z (0) = ∅ (die leere Menge)
Z (1) = {1}
Z (2) = {2}
Z (3) = {3} ({1, 2} ist nicht die Zeckendorf-Darstellung von 3)
Z. (10) = {5, 2}
Z (100) = {3, 5, 10}
Bei dieser Herausforderung werden Zeckendorf-Darstellungen als Bitmengen codiert, wobei das niedrigstwertige Bit darstellt, ob 1
es Teil der Menge usw. ist. Sie können davon ausgehen, dass die Zeckendorf-Darstellungen von Eingabe und Ausgabe in 31 Bit passen.
Ihre Aufgabe ist es, Z ( n + m ) mit Z ( n ) und Z ( m ) zu berechnen . Die Lösung mit der kürzesten Länge in Oktetten gewinnt.
Eine in ANSI C geschriebene Referenzimplementierung finden Sie hier . Es kann auch verwendet werden, um Zeckendorf-Darstellungen zu generieren oder eine Zahl aus seiner Zeckendorf-Darstellung zu berechnen.
Hier sind einige Paare von Beispieleingaben und -ausgaben, wobei die ersten beiden Spalten die Eingabe und die dritte Spalte die Ausgabe enthalten:
73865 9077257 9478805
139808 287648018 287965250
34 279004309 279004425
139940 68437025 69241105
272794768 1051152 273846948
16405 78284865 83888256
9576577 4718601 19013770
269128740 591914 270574722
8410276 2768969 11184785
16384 340 16724
Antworten:
K (ngn / k) ,
45 43 4241 BytesProbieren Sie es online aus!
@ Bubblers Algorithmus
{
}
Funktion mit Argumentx
64(
)/0
64-mal mit 0 als Anfangswert:1,
1 voranstellen+':
füge jeden Prior hinzu (lass das erste Element intakt)F:
zuweisenF
für "Fibonacci-Sequenz"|
umkehren(
..){y!x}\
.. beginnend mit dem Wert links, berechnen Sie die kumulativen Reste (von links nach rechts) für die Liste rechts. Der Wert links ist die einfache Summe der Eingaben ohne Zeckendorf-Darstellung:2\x
binär codieren die Eingänge. Dies wird eine nbits-by-2-Matrix sein|
umkehren+/'
Summe jeder&
wo sind die 1s - Liste der Indizes. Wenn es 2s gibt, wird der entsprechende Index zweimal wiederholt.F@
Array-Indizierung inF
+/
Summe<':
weniger als jeder vorherige (der erste des Ergebnisses wird immer falsch sein)2/
binäre Dekodierungquelle
CJam,
7674706359 BytesProbieren Sie es online im CJam-Interpreter aus oder überprüfen Sie alle Testfälle gleichzeitig .
Idee
Wir beginnen mit der Definition einer geringfügigen Variation der Sequenz in der Frage:
Auf diese Weise entspricht das Bit 0 (LSB) der eingegebenen oder ausgegebenen Bitarrays der Fibonacci-Zahl G 0 und im Allgemeinen dem Bit k bis G k .
Jetzt ersetzen wir jedes gesetzte Bit in Z (n) und Z (m) durch den Index, den es codiert.
Beispielsweise wird der Eingang 532 10 = 1000010100 2 in [2 4 9] umgewandelt .
Dies ergibt zwei Arrays von ganzen Zahlen, die wir zu einer einzigen verketten können.
Wenn beispielsweise n = m = 100 ist , ist das Ergebnis A: = [2 4 9 2 4 9] .
Wenn wir uns ersetzen k in A durch G k und die Ergebnisse addieren, so erhalten wir n + m = 200 , so A ist eine Art und Weise zu zersetzen 200 in Fibonacci - Zahlen, aber sicherlich nicht das einer vom Zeckendorf Theorem.
Wenn man bedenkt, dass G k + G k + 1 = G k + 2 und G k + G k = G k + G k-1 + G k-2 = G k + 1 + G k-2 , können wir aufeinanderfolgende ersetzen und doppelte Indizes von anderen (nämlich (k, k + 1) von k + 2 und (k, k) von (k + 1, k - 2) ), wobei diese Substitutionen immer wieder wiederholt werden, bis die Zeckendorf-Darstellung erreicht ist. 1
Für die resultierenden negativen Indizes muss ein Sonderfall berücksichtigt werden. Da G -2 = 0 ist , kann der Index -2 einfach ignoriert werden. Außerdem ist G -1 = 0 = G 0 , so dass jedes resultierende -1 durch 0 ersetzt werden muss .
Für unser Beispiel A erhalten wir die folgenden (sortierten) Darstellungen, wobei die letzte die Zeckendorf-Darstellung ist.
[2 2 4 4 9 9] → [0 3 4 4 9 9] → [0 5 4 9 9] → [0 6 9 9] → [0 6 7 10] → [0 8 10]
Schließlich konvertieren wir vom Array von Ganzzahlen zurück zum Bit-Array.
Code
1 Die Implementierung versucht 32-mal zu ersetzen und prüft nicht, ob die Zeckendorf-Darstellung tatsächlich erreicht wurde. Ich habe keinen formalen Beweis dafür, dass dies ausreichend ist, aber ich habe alle möglichen Summen von 15-Bit-Darstellungen getestet (deren Summenrepräsentationen bis zu 17 Bit erfordern) und 6 Wiederholungen waren für alle ausreichend. In jedem Fall ist es möglich, die Anzahl der Wiederholungen auf 99 zu erhöhen, ohne die Anzahl der Bytes zu erhöhen, dies würde jedoch die Leistung beeinträchtigen.
quelle
APL (Dyalog Extended) , 39 Bytes
Probieren Sie es online aus!
In ein vollständiges Programm mit einem Argument der Länge 2 geändert und auch der Fibonacci-Generator geändert. Vielen Dank an @ngn für viele Ideen.
Verwendet
⎕IO←0
so, dass⍳2
ausgewertet wird0 1
.Fibonacci-Generator (neu)
Beachten Sie, dass die letzten beiden Zahlen ungenau sind, die Ausgabe des Programms jedoch nicht geändert wird.
Zeckendorf zu schlicht (teilweise)
APL (Dyalog Extended) , 47 Bytes
Probieren Sie es online aus!
Teil 1 der vorherigen Antwort wurde geändert, um die Fibonacci-Zahlen wiederzuverwenden. Löschen Sie außerdem das Duplikat 1, um einige Bytes an anderen Stellen zu speichern.
Teil 1 (neu)
APL (Dyalog Extended) , 52 Bytes
Probieren Sie es online aus!
Wie es funktioniert
Kein ausgefallener Algorithmus zum Hinzufügen in Zeckendorf, da APL nicht für die Operation einzelner Elemente in einem Array bekannt ist. Stattdessen habe ich die beiden Eingaben von Zeckendorf in einfache Ganzzahlen konvertiert, hinzugefügt und zurückkonvertiert.
Teil 1: Zeckendorf zur einfachen ganzen Zahl
Teil 2: Fügen Sie zwei einfache Ganzzahlen hinzu
Teil 3: Wandle die Summe zurück nach Zeckendorf
"Sie können davon ausgehen, dass die Zeckendorf-Darstellungen von Eingabe und Ausgabe in 31 Bit passen" war ziemlich praktisch.
Der Fibonacci-Generator
Dies folgt aus der Eigenschaft von Fibonacci-Zahlen: wenn Fibonacci definiert ist als
dann
Fibonacci nach Zeckendorf Ziffern
quelle
Haskell, 325
396BytesEDIT: neue Version:
z
macht den Job.quelle
=
sind, sodass Eltern dort nicht benötigt werden , und so weiter und so fort, und beachten Sie, dass:
rechts assoziiert und Sie können einige dort schneiden. Aber trotzdem herzlichen Glückwunsch! Sieht sehr kompliziert aus. Ich kann es kaum erwarten herauszufinden, wie das funktioniert!ES6, 130 Bytes
Ich habe ursprünglich versucht, die Summe an Ort und Stelle zu berechnen (effektiv im Sinne der CJam-Implementierung), aber mir gingen immer wieder die temporären Werte aus, sodass ich nur die Zahlen in echte Ganzzahlen und zurück konvertierte.
(Ja, ich kann wahrscheinlich ein Byte mit eval speichern.)
quelle
Ruby ,
85 7365 BytesProbieren Sie es online aus!
Wie?
Erhalten Sie zuerst eine Obergrenze für die codierte Summe: (a + b) * 2 ist in Ordnung.
Filtern Sie nun alle Nicht-Zeckendorf-Zahlen aus (0..limit) heraus.
Wir haben eine Nachschlagetabelle, von hier geht es bergab.
quelle
Python 3, 207 Bytes
Probieren Sie es online aus! (Überprüfen Sie alle Testfälle)
Erläuterung
Dieses Programm bearbeitet direkt die binären Übersetzungen der Zeckendorf-Darstellungen. Die Funktion
a(n,m)
führt die Hauptberechnungen durch unds(n)
ist eine Hilfsfunktion, die benachbarte Zahlen in der Zeckendorf-Darstellung entfernt.Beginnen wir mit der Funktion
s(n)
(der Übersichtlichkeit halber erweitert):Zum Beispiel wird die Zahl 107 (
1101011
binär, die 1 + 2 + 5 + 13 + 21 = 42 darstellt) dem folgenden Prozess unterzogen:Probieren Sie es online aus! (s mit detaillierter Ausgabe)
Hier ist eine erweiterte Version von
a(n,m)
:Diese Funktion konvertiert die beiden Zeckendorf-Darstellungen in vier Binärzahlen, die einfacher zu kombinieren sind. Zeile (A) ist das bitweise ODER der beiden binären Zeckendorf-Darstellungen - diese entsprechen einer Kopie jeder Fibonacci-Zahl in jeder Gruppe. (B) und (C) sind das bitweise UND der beiden Zahlen, die 1 bzw. 2 Mal nach rechts verschoben sind. Wir wissen, dass wenn die entsprechenden Fibonacci-Zahlen für (B) und (C) addiert werden, sie dem bitweisen UND von uns entsprechen
n
undm
weil F (n) = F (n-1) + F (n-2) .Nehmen wir zum Beispiel an, wir haben die Binärzahlen n = 101001 (entsprechend 1 + 5 + 13) und m = 110110 (2 + 3 + 8 + 13). Dann haben wir (A) = 111111 (1 + 2 + 3 + 5 + 8 + 13), das durch unsere Funktion
s
(B) = 10000 (8) und (10) in 1010100 (3 + 8 + 21) umgewandelt wird C) = 1000 (5). Wir können überprüfen, ob (1 + 5 + 13) + (2 + 3 + 8 + 13) = (3 + 8 + 21) + (8) + (5) = 45. Dieser Vorgang wiederholt sich mit ((3 + 8 + 21) + (8)) + (5) = ((3 + 8 + 21) + (5) + (3)) + (5) usw.Die einzige Schwierigkeit bei diesem System ist, dass es für die Fibonacci-Zahlen 1 und 2 nicht funktioniert, da sie der Eigenschaft nicht gehorchen
F(n)=F(n-1)+F(n-2)
(sie sind die niedrigsten zwei Zahlen)! Aus diesem Grund wird immer dann, wenn 1 oder 2 in beiden enthalten sindn
undm
sie aus A, B und C entfernt werden, ihre Summe in D unter der Eigenschaft 1 + 1 = 2 und 2 + 2 = 1 + 3 platziert. Wenn wir zum Beispiel 1 + 3 (101) + 1 + 3 + 5 (1101) addieren, erhalten wir:(A): 3 + 5 (1100) = 8 (10000)
(B): 2 (10)
(C): 1 (1)
(D): 2 (10)
Beachten Sie, dass die 3 und 5 in A platziert wurden, das Duplikat 3 in B + C in 2 + 1 aufgeteilt wurde und das Duplikat 1 aus A, B und C entfernt, addiert und in D eingefügt wurde Addiere 2 + 3 (110) + 2 + 3 + 5 (1110), wir erhalten:
(A): 3 + 5 (1100) = 8 (10000)
(B): 2 (10)
(C): 1 (1)
(D): 1 + 3 (101)
Probieren Sie es online aus! (a mit detaillierter Ausgabe)
quelle
Wolfram Language (Mathematica) , 218 Bytes
Probieren Sie es online aus!
Einfach Mustervergleich.
Ungolfed:
quelle