Ist diese Nummer heimlich Fibonacci?

23

Hintergrund

Die meisten von Ihnen wissen, was eine Fibonacci-Zahl ist. Einige von Ihnen wissen vielleicht, dass alle positiven ganzen Zahlen nach dem Satz von Zeckendorf als Summe von einer oder mehreren unterschiedlichen Fibonacci-Zahlen dargestellt werden können . Wenn die Anzahl der Terme in der optimalen Zeckendorf-Darstellung einer ganzen Zahl nselbst eine Fibonacci-Zahl ist, werden wir n"heimlich" Fibonacci nennen.

Beispielsweise:

139 = 89 + 34 + 13 + 3
This is a total of 4 integers. Since 4 is not a Fibonacci number, 139 is not secretly Fibonacci

140 = 89 + 34 + 13 + 3 + 1
This is a total of 5 integers. Since 5 is a Fibonacci number, 140 is secretly Fibonacci

Anmerkungen

  • Die optimale Zeckendorf-Darstellung kann mit einem Greedy-Algorithmus ermittelt werden. Nehmen Sie einfach die größte Fibonacci-Zahl <= n und subtrahieren Sie sie von n, bis Sie 0 erreichen
  • Alle Fibonacci-Zahlen können als Summe von 1 Fibonacci-Zahl (selbst) dargestellt werden. Da 1 eine Fibonacci-Zahl ist, sind alle Fibonacci-Zahlen auch insgeheim Fibonacci.

Herausforderung

Ihre Herausforderung besteht darin, ein Programm oder eine Funktion zu schreiben, die eine Ganzzahl akzeptiert und zurückgibt, ob diese Ganzzahl heimlich Fibonacci ist.

Eingang

Sie können Eingaben in jedem vernünftigen Format vornehmen. Sie können davon ausgehen, dass die Eingabe eine einzelne positive Ganzzahl ist.

Ausgabe

Geben Sie eines von zwei unterschiedlichen Ergebnissen aus, um festzustellen, ob es sich bei der Eingabe um Fibonacci handelt. Beispiele sind True/ False, 1/ 0usw.

Wertung

Das ist , also gewinnt die kürzeste Antwort in Bytes! Standardlücken sind verboten.

Testfälle

Truthy (secretly Fibonacci)
1
2
4
50
140
300099

Falsey (NOT secretly Fibonacci)
33
53
54
139
118808
Cowabunghole
quelle
6
Bedeutet das, dass sie neugierig sind?
Kevin
2
Falls es jemandem von Nutzen ist: Die optimale Summe ist die eindeutige Lösung, bei der keine zwei aufeinander folgenden Fibonacci-Zahlen verwendet werden.
Kasperd
2
@kasperd Du hast recht, was Sinn macht, wenn du darüber nachdenkst. Wenn die Lösung zwei aufeinanderfolgende Fibonacci-Zahlen hätte, könnten sie zu der nächsten addiert werden. Wenn Ihre Lösung 5 und 8 enthalten würde, wäre sie weniger optimal als eine einzelne 13.
Cowabunghole 31.10.18
@Cowabunghole Das ist die Intuition. Ein vollständiger Beweis ist etwas komplizierter. Wenn die Lösung bereits 5, 8 und 13 enthielt, würden Sie 8 + 13 hinzufügen, nicht 5 + 8. Und die andere Richtung muss ebenfalls bewiesen werden.
Kasperd

Antworten:

8

Python 2 , 77 Bytes

def f(n):z=[bin(x).count('1')for x in range(n*n+1)if x&2*x<1];print z[z[n]]<2

Probieren Sie es online!

Dies nutzt den Satz, dass die beiden Beschreibungen von OEIS A003714 äquivalent sind:

n=F(i1)+F(i2)++F(ik)nna(n)=2i1+2i2++2ik1's.

zn

Dann bleibt zu prüfen, ob z[n]es sich um eine Fibonacci-Zahl handelt, dh z[z[n]] == 1.

n2+1

Lynn
quelle
Sie können zwei Bytes schneiden, indem Sie die Backticks entfernen bin(x). Sie können einen auch durch Ändern entfernen range(n*n+1)zu range(n<<n). (Angenommen, 0 ist ungültig)
nedla2004
Ich weiß nicht, was ich mit den Backticks gedacht habe bin(x), haha. Und, hm, 1<<nist schon viel, viel mehr als genug, aber ich möchte die Laufzeit nicht astronomisch halten
Lynn
Ich denke, der Code könnte ein wichtiges Attribut sein. :)
nedla2004
6

Gelee , 15 Bytes

‘ÆḞ€fRṪạµƬL’Ɗ⁺Ị

Ein monadischer Link, der eine nicht negative Ganzzahl akzeptiert, die 1"Secretly Fibonacci" ergibt, 0andernfalls.

Probieren Sie es online! (zu ineffizient für die größeren Testfälle)

Wie?

‘ÆḞ€fRṪạµƬL’Ɗ⁺Ị - Link: integer, I
        µƬ      - perform the monadic link to the left as a function of the current I,
                - collecting up all the inputs until the results are no longer unique:
‘               -   increment I -> I+1
 ÆḞ€            -   nth Fibonacci number for €ach n in [1,I+1]
     R          -   range from 1 to I
    f           -   filter discard (discard Fibonacci numbers not in the range, i.e. > I)
      Ṫ         -   tail (get the largest)
       ạ        -   absolute difference with I
                - This gives us a list from I decreasing by Fibonacci numbers to 0
                - e.g. for 88 we get [88,33,12,4,1,0]
                -      because (88-33)+(33-12)+(12-4)+(4-1)+(1-0)=55+21+8+3+1=88 
          L     - length (the number of Fibonacci numbers required plus one)
           ’    - decrement (the number of Fibonacci numbers required)
            Ɗ   - treat the last three links (which is everything to the left) as a monad:
             ⁺  - ...and repeat it
                - i.e. get the number of Fibonacci numbers required for the number of
                -      Fibonacci numbers required to represent I.
                -      This is 1 if I is Secretly Fibonacci, and greater if not)
              Ị - insignificant? (is the absolute value of that <= 1?)
Jonathan Allan
quelle
5

R 83 Bytes

function(n){T=1:0
while(n>T)T=c(T[1]+T[2],T)
while(n){n=n-T[T<=n][1]
F=F+1}
F%in%T}

Probieren Sie es online!

Giuseppe
quelle
5

C # (.NET Core) , 124 115 98 Bytes

a=>{int n=0,b,c;for(;a>0;a-=b,n++)for(b=c=1;c<=a;b=c-b)c+=b;for(b=c=1;c<n;c+=b)b=c-b;return c==n;}

Probieren Sie es online!

-3 Bytes: geändert in while-Schleife nach for (danke an Olivier Grégoire )
-6 Bytes: Umgeschaltete Rückgabe zur Verwendung von variablen, initialisierten b und c außerhalb von Schleifen (danke an Kevin Cruijssen )
-17 Bytes: geänderter Zustand in der zweiten Schleife zum Bewegen von if out of loop und kombiniere mit return, wiederverwendete b und c Variablen in der letzten Schleife (danke an raznagul )

Ungolfed:

a => {
    int n = 0, b, c;                        // initialize variables

    for(; a > 0; a -= b, n++)               // increase n until a is 0
        for(b = c = 1; c <= a; b = c - b)   // set b and c to 1 for each a; set second largest Fibonacci number until largest Fibonacci number reaches a
            c += b;                         // set largest Fibonacci number of current sequence

    for(b = c = 1; c < n; c += b)           // while e is less than or equal to n, continue incrementing largest (e) Fibonacci number in the sequence
        b = c - b;                          // increment second-largest (d) Fibonacci number

    return c == n;                          // if c equals n, a is a secret Fibonacci number
}
Erdmännchen
quelle
1
for(;c<=a;b=c-b)c+=b;Sie sparen 3 Bytes.
Olivier Grégoire
1
115 Bytes . Ich habe alle {}Klammern deiner Schleifen entfernt und alles in Schleifen gesteckt for. Außerdem habe ich eine Variable hinzugefügt, rdie wir 1in your festgelegt haben if(e==n)und am Ende zurückgeben, sodass Sie nur eine haben return.
Kevin Cruijssen
Guter Anruf zu beiden. Ich hatte versucht, die while-Schleife in eine for-Schleife zu ändern und irgendwie den einfachen Weg verpasst, dies zu tun. Es ist definitiv auch besser, eine separate Variable für die Rückgabe zu haben.
Erdmännchen
1
Indem Sie die Bedingung in der zweiten Schleife in ändern, können e<nSie das Zeichen ifnach der Schleife verschieben und sie anschließend mit dem Zeichenreturn für 101 Bytes kombinieren .
Raznagul
1
Sie können durch die Wiederverwendung noch 3 Bytes speichern bund cin der letzten Schleife und Entfernen dund e.
Raznagul
4

Perl 6 , 58 Bytes

{(1,&[+]...*>$_)∋($_,{$^n-(1,&[+]...^*>$n).tail}...0)-1}

Probieren Sie es online!

1, &[+] ... * > $_ ist nur die Fibonacci-Sequenz, die an einer bequemen, nicht unendlichen Stelle (der eingegebenen Nummer) angehalten wird.

$_, { $^n - (1, &[+] ...^ * > $n).tail } ... 0ist eine Folge von Zahlen, beginnend mit der eingegebenen Zahl und jedem nachfolgenden Element, das durch Subtrahieren der größten Fibonacci-Zahl, die kleiner oder gleich dem vorherigen Element ist, vom vorherigen Element erhalten wird. Die Sequenz endet, wenn 0erreicht ist. Wenn zum Beispiel $_ist 140, dann ist diese Sequenz 140, 51, 17, 4, 1, 0.

Das Subtrahieren von eins von dieser Sequenz behandelt es als eine Zahl, seine Länge und die Differenz ist die Anzahl der Fibonacci-Zahlen, die zusammen die eingegebene Zahl ergeben. Dann wird diese Nummer auf Mitgliedschaft in der ersten Fibonacci-Sequenz überprüft.

Sean
quelle
Ich habe diesen Trick noch nie gesehen &[+]! Schön, dass Sie nicht zwei anfängliche Begriffe definieren müssen
Jo King
1
51 Bytes durch Zuweisen der Fibonacci-Sequenz zu einer Funktion und ein paar andere Änderungen
Jo King
Port of l4m2 JavaScript-Antwort, 50 Bytes
Nwellnhof
@nwellnhof Ha, ich hatte so ziemlich das Gleiche, bis auf einen kleinen Unterschied
Jo King
3

Perl 6 , 48 Bytes

{4>($_,{$_,{$_-(1,&[+]...*>$_)[*-2]}...^0}...1)}

Probieren Sie es online!

Transformiert die Eingabe wiederholt in eine Liste der Zeckendorf-Darstellung, bis eine einzelne Zahl erreicht ist, und überprüft dann, ob die Länge der Sequenz kürzer als 4 war.

Die Zenckendorf-Funktion in der Mitte stammt größtenteils aus Seans Antwort mit ein paar Verbesserungen.

Erläuterung:

{4>($_,{$_,{$_-(1,&[+]...*>$_)[*-2]}...^0}...1)}
{                                              } # Anonymous code block
                                          ...     # Define a sequence:
    $_  # That starts at the input
      ,{                                 }  # Each element is defined by:
                                   ... # Another sequence that:
        $_,   # Starts at the previous element
            $_-   # The previous element minus
                1,&[+]...*     # The Fibonacci sequence
                          >$_  # Ending when it is larger than the previous element
               (             )[*-2]  # The second from last element
          {                        }...^0  # Run until 0, discarding the last element
         # This returns the length of the Zeckendorf Representation
                                         ...1  # Run this until it is length 1
 4>(                                         )  # Return true if the length of the sequence is smaller than 4

Zum Beispiel kann die Sequenz für 2IS 2 1da 2bereits eine Fibonacci - Zahl. Die Sequenz für 140ist 140 5 1, und da 5 eine Fibonacci-Zahl ist, gibt dies wahr zurück. Die Folge für 33ist 33 4 2 1, und da 4es sich nicht um eine Fibonacci-Zahl handelt, hat die Folge die Länge 4.

Scherzen
quelle
3

05AB1E , 14 Bytes

ΔDÅFθ-¼}¾ÅF¾<å

Probieren Sie es online aus . Keine Testsuite für alle Testfälle, da counter_variablediese nicht auf 0 zurückgesetzt werden können. Ich habe sie jedoch alle von Hand überprüft und sie sind korrekt.

Erläuterung:

Δ      }          # Loop until the top of the stack no longer changes
 D                #  Duplicate the top of the stack
                  #  (implicitly the input in the first iteration)
  ÅF              #  Get a list of all Fibonacci numbers lower than this number
    θ             #  Get the last item (largest one)
     -            #  Subtract it from the number
      ¼           #  Increase the counter_variable by 1 every iteration
        ¾         # After the loop, push the counter_variable
         ÅF       # Get all Fibonacci numbers below this counter_variable
           ¾<     # Push the counter_variable again, and subtract 1
             å    # Check if this value is in the list of Fibonacci numbers
                  # (and output implicitly)

ANMERKUNG: Das counter_variablewäre 5für die Eingabe 139und 6für die Eingabe 140, da Δes natürlich eine zusätzliche Iteration gibt, damit die Schleife den Stapel überprüft.

Kevin Cruijssen
quelle
2

Retina 0.8.2 , 61 Bytes

.+
$*
M`((?>\2?)(\1|\G.))*..|.
.+
$*
^(((?>\3?)(\2|^.))*.)?.$

Probieren Sie es online! Link enthält Testfälle. Erläuterung:

.+
$*

In Unary konvertieren.

M`((?>\2?)(\1|\G.))*..|.

Zählen Sie die Anzahl der benötigten Fibonacci-Zahlen.

Die erste Alternative behandelt Fibonacci-Zahlen, die mindestens 2 sind. Im ersten Durchgang ist sie \2noch nicht vorhanden, aber zum Glück ist sie optional, sodass wir sie nicht abgleichen müssen. \1gibt es auch nicht, aber zum Glück haben wir die Alternative, \G.bei der zu Beginn des Spiels ein einzelnes Zeichen gefunden wird. Beide \2und \1nehmen daher den Wert 1 an.

In den folgenden Durchläufen ist \2vorhanden, daher versuchen wir, eine Übereinstimmung zu erzielen. Dieses Mal, wenn es fehlschlägt, \1schlägt es ebenfalls fehl (da es größer als ist \2), aber wenn es erfolgreich ist, (?>)verhindert das das Zurückverfolgen. Wenn also \2Übereinstimmungen vorliegen, \1versuchen wir es nicht einfach \1. ( \G1Schlägt immer fehl, da wir den Patch-Start überschritten haben.) Nimmt schließlich \2den vorherigen Wert von \1while an\1 nimmt die Summe der beiden Werte an.

Wir gleichen daher so viele Fibonacci-Zahlen wie möglich ab und addieren sie nacheinander. Da die Teilsummen der Folge 1, 2, 3, 5...sind0, 1, 3, 6, 11... also zwei weniger als die Fibonacci - Zahlen , die wir durch passende 2 am Ende zu beenden.

Dies entspricht offensichtlich nicht 1 selbst, so dass eine Abwechslung diesen Fall behandelt.

.+
$*

In Unary konvertieren.

^(((?>\3?)(\2|^.))*.)?.$

Testen Sie, ob dies eine Fibonacci-Zahl ist. Hierbei wird die gleiche Idee wie beim ersten Test verwendet, jedoch ^nicht\G Außerdem müssen wir genau übereinstimmen. Daher wird anstelle einer Abwechslung ein optionales Capture verwendet, da dies Golfspieler ist (jedoch werden die Capture-Nummern um 1 erhöht).

Retina , 35 Bytes

.+
*
2}C`((?>\2?)(\1|\G.))*..|.
^1$

Probieren Sie es online! Link enthält Testfälle. Erläuterung:

.+
*

In Unary konvertieren.

C`((?>\2?)(\1|\G.))*..|.

Zählen Sie die Anzahl der benötigten Fibonacci-Zahlen. (Durch Schleifen von Konvertierung und Zählung wird ein ganzes Byte gespart, da die Zählung erst einmal unärgerlich wird.)

2}

Führen Sie die vorherigen Schritte insgesamt zweimal aus. Dies berechnet die Anzahl der Fibonacci-Zahlen, die benötigt werden, um die Anzahl der Fibonacci-Zahlen zu summieren.

^1$

Wenn die Zahl heimlich Fibonacci war, ist das Ergebnis 1.

Neil
quelle
1

Python 2 , 146 137 Bytes

lambda a:len(g(len(g(a))))<2
f=lambda n:n<3or f(n-2)+f(n-1)
def g(a,n=1):j=f(n-1);return[j]if a-j<1else[j]+g(a-j)if a-f(n)<0else g(a,n+1)

Probieren Sie es online!

f () ist eine rekursive Funktion, die den Wert der n-ten Fibonacci-Zahl zurückgibt. Aus dieser Antwort entnommen .

g () ist eine rekursive Funktion, die die Zeckendorf-Darstellung der angegebenen Zahl als Liste von ganzen Zahlen zurückgibt.

Da alle Fibonacci-Zahlen eine Rückgabelänge von einem Element von g () haben, prüft h (), ob die Länge von g () von g (n) == 1 ist.

BEARBEITEN: 9 Bytes dank nedla2004 gespeichert . Ich vergesse immer wieder, dass Lambdas nicht immer die beste Lösung sind ...

Triggernometrie
quelle
1
138 Bytes . Ich habe meistens nur geine Funktion erstellt, damit ich sie f(n-1)für eine Variable definieren kann. Paar andere Änderungen von ==zu , <wo sie gleich sind.
Nedla2004