Interpolation linéaire de la séquence de Fibonacci

20

Votre tâche consiste à trouver le n ème nombre de Fibonacci, mais n n'est pas nécessairement un entier.

La séquence de Fibonacci, indexée 0, se présente comme suit:

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

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

Mais que se passe-t-il si nous voulons le 2, 4 e nombre?

Le 2,4 ème nombre est 0,4 fois la différence entre les 3 ème et 2 ème numéros de Fibonacci plus le 2 ème numéro de Fibonacci. Ainsi, le 2,4 e nombre de Fibonacci est 2 + 0.4 * (3 – 2) = 2.4.

De même, le 6,35 e nombre de Fibonacci est 13 + 0.35 * (21 – 13) = 15.8.

Votre tâche consiste à trouver le n ème nombre de Fibonacci, tel que n soit supérieur ou égal à 0.

Vous pouvez le faire à zéro ou à un index, veuillez simplement dire lequel vous utilisez.

C'est le , donc le code le plus court en octets gagne!

Quelques exemples supplémentaires:

0        1
4.5    6.5
0.7      1
7       21
Daniel
la source
2
L'opération que vous effectuez ici est appelée "interpolation linéaire". (Cela vous dérangerait si je modifiais le titre de l'article pour refléter cela?) Il semble que la propriété Fibonacci soit f (n-2) + f (n-1) = f (n), donc je suppose que c'est une généralisation raisonnable de la séquence de Fibonacci. (Je ne sais pas s'il y a une généralisation standard.)
@ ais523, si vous pensez que cela améliorerait la question, alors oui, vous pouvez changer le titre du message.
Daniel
Je pense que cela rendra la question plus facile à trouver à l'avenir si quelqu'un demande quelque chose de similaire, et rend également plus clair de quoi il s'agit dans, disons, la liste "Connexes". Cela améliorera donc la question en aidant à placer les répondeurs au bon endroit.
2
@ais On dirait qu'il y a une généralisation de la formule de Binet: mathworld.wolfram.com/FibonacciNumber.html
Neil
1
Bien que le golf de code n'ait pas à justifier la demande (je suppose), cela semble être une opération étrange; selon elle, depuis F_0 = 0et F_2 = 1, nous aurions dû F_1 = (1/2)(F_0 + F_2) = 1/2.
LSpice

Réponses:

7

Gelée , 5 octets

_Ḟ1+¡

Il s'agit d'une solution itérative sans fonctions intégrées. Il utilise la même indexation que la spécification de défi.

Essayez-le en ligne!

Contexte

Soit f la fonction définie dans la spécification de défi et F la fonction de Fibonacci définie comme d'habitude (c'est-à-dire avec F (0) = 0 ). Pour un entier non négatif n , nous avons f (n) = F (n + 1) . Lorsque 0 ≤ x <1 , la spécification de défi définit f (n + x) comme f (n) + (f (n + 1) - f (n)) x .

De toute évidence, cela affecte seulement les cas de base, mais non pas la formule de récurrence, soit f (n) = f (n - 1) + f (n - 2) tient comme il le ferait pour F . Cela signifie que nous pouvons simplifier la définition d'arguments non entiers vers le plus facile f (n) = f (n) + f (n - 1) x .

Comme d'autres l'ont noté dans leurs réponses, la relation récursive s'applique également aux arguments non entiers. Ceci est facilement vérifiable, car

preuve

Puisque f (0) = f (1) = 1 , f en constante dans l'intervalle [0, 1] et f (0 + x) = 1 pour tout x . De plus, f (-1) = F (0) = 0 , donc f (-1 + x) = f (-1) + (f (0) - f (-1)) x = 0 + 1x = x . Ces cas de base couvrent en [-1, 1) , donc avec la formule récursive, ils complètent la définition de f .

Comment ça fonctionne

Comme précédemment, soit n + x le seul argument de notre programme monadique.

¡est un rapide , ce qui signifie qu'il consomme des liens à sa gauche et les transforme en un lien rapide . ¡consomme notamment un ou deux liens.

  • <F:monad|dyad><N:any>appelle le lien N , renvoyant r , et exécute F un total de r fois.

  • <nilad|missing><F:monad|dyad>définit r au dernier argument de la ligne de commande (ou une entrée de STDIN en leur absence) et exécute F un total de r fois.

Puisque 1c'est un nilad (un lien sans arguments), le second cas s'applique et s'exécutera + n fois (un argument non entier est arrondi vers le bas). Après chaque appel à +, l'argument de gauche du lien rapide est remplacé par la valeur de retour et l'argument de droite par la valeur précédente de l'argument de gauche.

Comme pour tout le programme, les planchers d'entrée, donnant n ; puis _soustrayez le résultat de l'entrée, ce qui donne ** x, qui devient la valeur de retour.

1+¡appelle ensuite - comme décrit précédemment - avec l'argument gauche 1 = f (0 + x) et l'argument droit x = f (-1 + x) , qui calcule la sortie souhaitée.

Dennis
la source
Ahh, à quel point est utile pour les défis de Fibonacci. Était-ce utile d'avoir du ¡travail comme fibonacci avec des dyades?
Erik the Outgolfer
Oooh - %1+¡: interpolation linéaire entre n × F (n) à n et n × F (n-1) + F (n) à n-ε , et augmenter entre n-ε et n .
Jonathan Allan
@EriktheOutgolfer Eh bien, plus ou moins. Comme Jelly n'a pas de variables, vous perdriez autrement l'accès aux membres de la séquence précédente, il était donc logique de l'implémenter comme ceci.
Dennis
@JonathanAllan Je ne suis pas sûr de comprendre. Que faut-il %1+¡faire?
Dennis
@Derma erm, ça voulait dire , bien \ _o_ / ... mais c'est ce que cela semble faire avec l'expérimentation: D
Jonathan Allan
5

Mathematica, 32 octets

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

Fonction pure prenant un nombre réel non négatif en entrée et retournant un nombre réel. S'il 1~Max~#était remplacé par 1, ce serait la définition récursive standard des nombres de Fibonacci indexés sur 0 pour les arguments entiers. Mais 1~Max~#c'est la fonction linéaire par morceaux correcte pour les entrées réelles entre 0 et 2, et la récursivité s'occupe du reste. (Anecdote: changer cela en nombres de Fibonacci indexés 1 peut être accompli simplement en changeant le Maxen a Min!)

Le plus court que j'ai pu obtenir avec la fonction intégrée est le 37 octets (b=Fibonacci)[i=Floor@#](#-i)+b[i+1]&.

Greg Martin
la source
3

JavaScript (ES6), 30 octets

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>

Modification triviale de la définition de séquence de Fibonacci récursive à index zéro. Peut donner de légères erreurs d'arrondi pour certaines entrées.

ETHproductions
la source
C'est intelligent. Je pensais que cela ne fonctionnait pas.
Leaky Nun
1

Gelée , 17 12 octets

’Ñ+Ñ
’»0‘ÇỊ?

Essayez-le en ligne!

Solution non intégrée.

Explication

Fonction d'assistance 1Ŀ

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

Programme principal

’»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

Une entrée dans la plage 0 à 1 sera donc saturée-soustraite à 0, donc on ajoute 1 pour obtenir F (0) = F (1) = 1. Une entrée dans la plage 1 à 2 se renverra. Ces cas de base sont suffisants pour effectuer une récursivité de Fibonacci typique et calculer les autres valeurs à partir de là.


la source
1

Excel, 137 124 119 113 102 102 97 octets

Approche non récursive / itérative. (Calculez directement les nèmes termes) Cela utilise la méthode à un index . L'ajout +1de le =TRUNC(B1)change en indexé zéro.

=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

L'extrait de code est destiné à être placé à partir de la cellule A1 .

La cellule d'entrée est B1 . La cellule de sortie est A1 .

qoou
la source
1

JavaScript (ES6), 67 64 octets

A quelques problèmes d'arrondi

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

Essayez-le

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))

Hirsute
la source
0

PHP, 90 octets

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

Version en ligne

Jörg Hülsermann
la source
0

Gelée , 13 9 octets

,‘ḞÆḞḅ%1$

Cela utilise la même indexation que la spécification de défi.

Essayez-le en ligne!

Contexte

Selon la spécification, nous avons F (n + x) = F (n) + (F (n + 1) - F (n)) x , pour n naturel et 0 ≤ x <1 . Puisque F (n + 1) = F (n) + F (n - 1) , cela peut être réécrit comme F (n + x) = F (n) + F (n - 1) x .

De plus, l'indexation utilisée dans la spécification de défi définit une fonction f (n) = F (n + 1) (où F est la fonction Fibonacci habituelle, c'est-à-dire F (0) = 0 ), nous obtenons donc la formule f (n + x) = F (n + 1) + F (n) x .

Comment ça fonctionne

,‘ḞÆḞḅ%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
la source
0

Perl 6 ,  48  38 octets

48

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

Essayez-le

38

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

Essayez-le

Étendu:

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
}

( $0et $1est l'abréviation de $/[0]et $/[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
}

Cela a été inspiré par d'autres solutions Python et Javascript

Brad Gilbert b2gills
la source