Lineare Interpolation der Fibonacci-Sequenz

20

Ihre Aufgabe ist es, die n- te Fibonacci-Zahl zu finden, aber n muss nicht unbedingt eine ganze Zahl sein.

Die mit 0 indizierte Fibonacci-Sequenz lautet wie folgt:

0, 1, 2, 3, 4, 5,  6,  7, ...

1, 1, 2, 3, 5, 8, 13, 21, ...

Was passiert jedoch, wenn wir die 2,4- te Zahl wollen?

Die 2,4- te Zahl ist das 0,4-fache der Differenz zwischen der dritten und der zweiten Fibonacci-Zahl plus der zweiten Fibonacci-Zahl. So ist die 2.4 th ist Fibonacci - Zahl 2 + 0.4 * (3 – 2) = 2.4.

Ähnlich ist die 6.35 th ist Fibonacci - Zahl 13 + 0.35 * (21 – 13) = 15.8.

Ihre Aufgabe ist es, die n- te Fibonacci-Zahl zu finden, sodass n größer oder gleich 0 ist.

Sie können dies null- oder einsindiziert tun, sagen Sie einfach, welches Sie verwenden.

Das ist , also gewinnt der kürzeste Code in Bytes!

Einige weitere Beispiele:

0        1
4.5    6.5
0.7      1
7       21
Daniel
quelle
2
Die Operation, die Sie hier ausführen, wird als "lineare Interpolation" bezeichnet. (Würde es Ihnen etwas ausmachen, wenn ich den Titel des Beitrags ändern würde, um dies widerzuspiegeln?) Es scheint die Fibonacci-Eigenschaft zu haben, dass f (n-2) + f (n-1) = f (n), also denke ich, dass dies ist eine vernünftige Verallgemeinerung der Fibonacci-Sequenz. (Ich bin nicht sicher, ob es eine Standard-Verallgemeinerung gibt.)
@ ais523, wenn du denkst, dass es die Frage verbessern würde, kannst du den Titel des Beitrags ändern.
Daniel
Ich denke, es wird die Frage in Zukunft leichter zu finden machen, wenn jemand etwas Ähnliches fragt, und es wird auch klarer, worum es geht, sagen wir, in der "Related" -Liste. Die Frage wird dadurch besser, dass die Antwortenden an den richtigen Ort gebracht werden.
2
@ais Sieht so aus, als gäbe es eine Verallgemeinerung der Binet-Formel: mathworld.wolfram.com/FibonacciNumber.html
Neil
1
Obwohl Code Golf die Anfrage nicht rechtfertigen muss (denke ich), scheint dies eine seltsame Operation zu sein; demnach sollten wir seit F_0 = 0und F_2 = 1haben F_1 = (1/2)(F_0 + F_2) = 1/2.
LSpice

Antworten:

7

Gelee , 5 Bytes

_Ḟ1+¡

Dies ist eine iterative Lösung ohne integrierte Funktionen. Es wird die gleiche Indizierung wie für die Challenge-Spezifikation verwendet.

Probieren Sie es online!

Hintergrund

Sei f die in der Challenge-Spezifikation definierte Funktion und F die wie üblich definierte Fibonacci-Funktion (dh mit F (0) = 0 ). Für eine nicht negative ganze Zahl n gilt f (n) = F (n + 1) . Wenn 0 ≤ x <1 ist , definiert die Herausforderungsspezifikation f (n + x) als f (n) + (f (n + 1) - f (n)) x .

Natürlich betrifft dies nur die Basis Fällen, aber nicht die rekursive Formel, dh f (n) = f (n - 1) + f (n - 2) hält , wie es wäre für F . Dies bedeutet, dass wir die Definition für nicht ganzzahlige Argumente vereinfachen können, um f (n) = f (n) + f (n - 1) x zu vereinfachen .

Wie andere in ihren Antworten angemerkt haben, gilt die rekursive Beziehung auch für nicht ganzzahlige Argumente. Dies ist leicht nachprüfbar, da

Beweis

Da f (0) = f (1) = 1 ist , ist f im Intervall [0, 1] konstant und f (0 + x) = 1 für alle x . Weiterhin ist f (-1) = F (0) = 0 , so dass f (-1 + x) = f (-1) + (f (0) - f (-1)) x = 0 + 1x = x . Diese Basisfälle decken [-1, 1) ab , sodass sie zusammen mit der rekursiven Formel die Definition von f vervollständigen .

Wie es funktioniert

Nach wie vor sei n + x das einzige Argument unseres monadischen Programms.

¡ist ein Quicklink , das heißt, er verbraucht einige Links zu seiner Linken und verwandelt sie in einen Quicklink . ¡verbraucht insbesondere entweder ein oder zwei Links.

  • <F:monad|dyad><N:any>ruft die Verbindung N auf , gibt r zurück und führt F insgesamt r- mal aus.

  • <nilad|missing><F:monad|dyad>Sätze r zur letzten Befehlszeilenargument (oder eine Eingabe von STDIN in ihrer Abwesenheit) und führt F insgesamt r mal.

Da 1es sich um einen Nullwert (eine Verknüpfung ohne Argumente) handelt, gilt der zweite Fall und wird + n- mal ausgeführt (ein nicht ganzzahliges Argument wird abgerundet). Nach jedem Aufruf von +wird das linke Argument des Quicklinks durch den Rückgabewert und das rechte Argument durch den vorherigen Wert des linken Arguments ersetzt.

Für das gesamte Programm wird die Eingabe überschrieben, was n ergibt . _Subtrahieren Sie dann das Ergebnis von der Eingabe und erhalten Sie ** x, das zum Rückgabewert wird.

1+¡ruft dann - wie zuvor beschrieben - mit linkem Argument 1 = f (0 + x) und rechtem Argument x = f (-1 + x) auf , was die gewünschte Ausgabe berechnet.

Dennis
quelle
Ahh, wie nützlich ist es für Fibonacci-Herausforderungen? War es ¡sinnvoll, mit Dyaden wie Fibonacci zu arbeiten?
Erik der Outgolfer
Oooh - %1+¡: lineare Interpolation zwischen n × F (n) bei n und n × F (n - 1) + F (n) bei n - & epsi ; und Aufwärtsschritt zwischen n - & epsi; und n .
Jonathan Allan
@EriktheOutgolfer Na ja, mehr oder weniger. Da Jelly keine Variablen hat, würden Sie ansonsten den Zugriff auf die vorherigen Sequenzmitglieder verlieren. Es war also sinnvoll, dies so zu implementieren.
Dennis
@ JonathanAllan Ich bin nicht sicher, ob ich das verstehe. Was %1+¡soll ich tun?
Dennis
@Dennis ähm, gemeint , na ja, aber genau das scheint es mit Experimenten zu tun zu haben: D
Jonathan Allan
5

Mathematica, 32 Bytes

If[#<2,1~Max~#,#0[#-1]+#0[#-2]]&

Reine Funktion, die eine nichtnegative reelle Zahl als Eingabe verwendet und eine reelle Zahl zurückgibt. Wenn dies 1~Max~#durch ersetzt 1würde, wäre dies die standardmäßige rekursive Definition der 0-indizierten Fibonacci-Zahlen für ganzzahlige Argumente. Ist 1~Max~#aber die richtige stückweise lineare Funktion für reelle Eingaben zwischen 0 und 2, und die Rekursion kümmert sich um den Rest. (Wissenswertes: Um dies in die 1-indizierten Fibonacci-Zahlen umzuwandeln, müssen Sie einfach das Maxin a Min! Ändern. )

Das kürzeste, was ich mit dem eingebauten bekommen konnte, ist das 37-Byte (b=Fibonacci)[i=Floor@#](#-i)+b[i+1]&.

Greg Martin
quelle
3

JavaScript (ES6), 30 Byte

f=x=>x<1?1:x<2?x:f(x-1)+f(x-2)
<input type=number value=2.4 oninput="O.value=f(value)"> <input id=O value=2.4 disabled>

Triviale Modifikation der nullindexierten rekursiven Fibonacci-Sequenzdefinition. Bei einigen Eingaben können leichte Rundungsfehler auftreten.

ETHproductions
quelle
Das ist schlau. Ich dachte, es hat nicht funktioniert.
Undichte Nonne
1

Jelly , 17 12 Bytes

’Ñ+Ñ
’»0‘ÇỊ?

Probieren Sie es online!

Nicht eingebaute Lösung.

Erläuterung

Hilfsfunktion 1Ŀ

’Ñ+Ñ
 Ñ    Call the main program on
’       {the input} - 1;
   Ñ  Call the main program on {the input};
  +   Add those results{and return the result}

Hauptprogramm

’»0‘ÇỊ?
’        Subtract 1
 »0      but replace negative results with 0
     Ị?  If the result is less than or equal to 1
   ‘     Return the result plus 1
    Ç    else return the result

Eine Eingabe im Bereich von 0 bis 1 wird daher zu 0 gesättigt subtrahiert, daher addieren wir 1, um F (0) = F (1) = 1 zu erhalten. Eine Eingabe im Bereich von 1 bis 2 gibt sich von selbst zurück. Diese Basisfälle reichen aus, um eine typische Fibonacci-Rekursion durchzuführen und die anderen Werte von dort zu berechnen.


quelle
1

Excel, 137 124 119 113 102 97 Bytes

Nicht rekursiver / iterativer Ansatz. (Berechnen Sie direkt die n-ten Terme.) Hierbei wird die Methode mit einem Index verwendet. Durch Hinzufügen +1zu wird =TRUNC(B1)der Index auf Null gesetzt.

=A7+(A8-A7)*MOD(B1,1)
=5^.5
=(1+A2)/2
=TRUNC(B1)
=A4+1
=-1/A3
=(A3^A4-A6^A4)/A2
=(A3^A5-A6^A5)/A2

Das Code-Snippet soll ab Zelle A1 platziert werden .

Die Eingabezelle ist B1 . Die Ausgabezelle ist A1 .

qoou
quelle
1

JavaScript (ES6), 67 64 Bytes

Hat ein paar Probleme mit der Rundung

n=>(i=(g=(z,x=1,y=0)=>z?g(--z,x+y,x):y)(++n|0))+n%1*(g(++n|0)-i)

Versuch es

f=
n=>(i=(g=(z,x=1,y=0)=>z?g(--z,x+y,x):y)(++n|0))+n%1*(g(++n|0)-i)
console.log(f(2.4))
console.log(f(6.35))
console.log(f(42.42))

Zottelig
quelle
0

PHP, 90 Bytes

for($f=[1,1];$i<$a=$argn;)$f[]=$f[+$i]+$f[++$i];echo$f[$b=$a^0]+($a-$b)*($f[$b+1]-$f[$b]);

Online Version

Jörg Hülsermann
quelle
0

Jelly , 13 9 Bytes

,‘ḞÆḞḅ%1$

Dies verwendet die gleiche Indizierung wie die Herausforderungsspezifikation.

Probieren Sie es online!

Hintergrund

Gemäß der Spezifikation gilt F (n + x) = F (n) + (F (n + 1) - F (n)) x für natürliches n und 0 ≤ x <1 . Da F (n + 1) = F (n) + F (n - 1) ist , kann dies als F (n + x) = F (n) + F (n - 1) x umgeschrieben werden .

Darüber hinaus definiert die in der Herausforderungsspezifikation verwendete Indizierung eine Funktion f (n) = F (n + 1) (wobei F die übliche Fibonacci-Funktion ist, dh F (0) = 0 ), sodass wir die Formel f (n) erhalten + x) = F (n + 1) + F (n) x .

Wie es funktioniert

,‘ḞÆḞḅ%1$  Main link. Argument: n + x

 ‘         Increment; yield n + 1 + x.
,          Pair; yield [n + x, n + 1 + x].
  Ḟ        Floor; yield [n, n + 1].
   ÆḞ      Fibonacci; yield [F(n), F(n + 1)].
      %1$  Modulus 1; yield (n + x) % 1 = x.
     ḅ     Unbase; yield F(n)x + F(n + 1).
Dennis
quelle
0

Perl 6 ,  48  38 Bytes

48

{$/=(1,1,*+*...*)[$_,$_+1];$0+($_-.Int)*($1-$0)}

Versuch es

38

sub f(\n){3>n??max 1,n!!f(n-1)+f(n-2)}

Versuch es

Erweitert:

48

{
  $/ =          # store here so we can use $0 and $1
  (
    1,1,*+*...* # Fibonacci sequence
  )[
    $_,         # get the value by using floor of the input
    $_ + 1      # and get the next value
  ];

    $0            # the first value from above
  +
    ( $_ - .Int ) # the fractional part of the input
  *
    ( $1 - $0 )   # the difference between the two values in the sequence
}

( $0und $1steht für $/[0]und $/[1])

38

sub f (\n) {
    3 > n           # if n is below 3
  ??
    max 1, n        # return it if it is above 1, or return 1
                    # if it was below 1, the answer would be 1
                    # the result for numbers between 1 and 3
                    # would be the same as the input anyway
  !!
    f(n-1) + f(n-2) # the recursive way to get a fibonacci number
}

Dies wurde von anderen Python- und Javascript- Lösungen inspiriert

Brad Gilbert b2gills
quelle