Interpolación lineal de la secuencia de Fibonacci.

20

Su tarea es encontrar el n º número de Fibonacci, pero n no es necesariamente un número entero.

La secuencia de Fibonacci, indexada en 0, es la siguiente:

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

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

Sin embargo, ¿qué ocurre si queremos que el 2 0.4 º número?

El 2,4 º número es de 0,4 veces la diferencia entre la 3 rd y 2 nd números de Fibonacci más el 2 nd número de Fibonacci. Entonces, el número 2.4 de Fibonacci es 2 + 0.4 * (3 – 2) = 2.4.

Del mismo modo, el número 6.35 de Fibonacci es 13 + 0.35 * (21 – 13) = 15.8.

Su tarea es encontrar el n º número de Fibonacci, de modo que n es mayor o igual a 0.

Puede hacer esto con un índice cero o uno, solo indique cuál está usando.

Este es el , por lo que gana el código más corto en bytes.

Algunos ejemplos más:

0        1
4.5    6.5
0.7      1
7       21
Daniel
fuente
2
La operación que está haciendo aquí se llama "interpolación lineal". (¿Le importaría si cambiara el título de la publicación para reflejar eso?) Parece tener la propiedad de Fibonacci que f (n-2) + f (n-1) = f (n), así que supongo que esto es Una generalización razonable de la secuencia de Fibonacci. (No estoy seguro de si hay alguna generalización estándar)
@ ais523, si crees que mejoraría la pregunta, entonces sí, puedes cambiar el título de la publicación.
Daniel
Creo que hará que la pregunta sea más fácil de encontrar en el futuro si alguien pregunta algo similar, y también aclara de qué se trata, por ejemplo, en la lista "Relacionados". Por lo tanto, mejorará la pregunta al ayudar a los respondedores al lugar correcto.
2
@ais Parece que hay una generalización de la fórmula de Binet: mathworld.wolfram.com/FibonacciNumber.html
Neil
1
Aunque el código de golf no tiene que justificar la solicitud (supongo), esto parece una operación extraña; de acuerdo con esto, desde F_0 = 0y F_2 = 1, deberíamos haberlo hecho F_1 = (1/2)(F_0 + F_2) = 1/2.
LSpice

Respuestas:

7

Jalea , 5 bytes

_Ḟ1+¡

Esta es una solución iterativa sin elementos integrados. Utiliza la misma indexación que la especificación de desafío.

Pruébalo en línea!

Antecedentes

Sea f la función definida en la especificación de desafío y F la función de Fibonacci definida como de costumbre (es decir, con F (0) = 0 ). Para un número entero no negativo n , tenemos f (n) = F (n + 1) . Cuando 0 ≤ x <1 , la especificación de desafío define f (n + x) como f (n) + (f (n + 1) - f (n)) x .

Claramente, esto sólo afecta a los casos base, pero no la fórmula recursiva, es decir, f (n) = f (n - 1) + f (n - 2) ejerce como lo haría para F . Esto significa que podemos simplificar la definición de argumentos no enteros a f (n) = f (n) + f (n - 1) x más fácil .

Como otros han señalado en sus respuestas, la relación recursiva también es válida para argumentos no enteros. Esto es fácilmente verificable, ya que

prueba

Desde f (0) = f (1) = 1 , f en constante en el intervalo [0, 1] y f (0 + x) = 1 para todos x . Además, f (-1) = F (0) = 0 , entonces f (-1 + x) = f (-1) + (f (0) - f (-1)) x = 0 + 1x = x . Estos casos básicos cubren en [-1, 1) , por lo que junto con la fórmula recursiva, completan la definición de f .

Cómo funciona

Como antes, dejemos que n + x sea ​​el único argumento de nuestro programa monádico.

¡es un rápido , lo que significa que consume algunos enlaces a su izquierda y los convierte en un enlace rápido . ¡en particular consume uno o dos enlaces.

  • <F:monad|dyad><N:any>llama al enlace N , devuelve r , y ejecuta F un total de r veces.

  • <nilad|missing><F:monad|dyad>establece r en el último argumento de línea de comandos (o una entrada de STDIN en su ausencia) y ejecuta F un total de r veces.

Como 1es un nilad (un enlace sin argumentos), se aplica el segundo caso, y se ejecutará + n veces (un argumento no entero se redondea hacia abajo). Después de cada llamada a +, el argumento izquierdo del enlace rápido se reemplaza con el valor de retorno, y el argumento derecho con el valor anterior del argumento izquierdo.

En cuanto a todo el programa, coloca la entrada, produciendo n ; luego _reste el resultado de la entrada, produciendo ** x, que se convierte en el valor de retorno.

1+¡luego llama , como se describió anteriormente, con el argumento izquierdo 1 = f (0 + x) y el argumento derecho x = f (-1 + x) , que calcula la salida deseada.

Dennis
fuente
Ah, qué útil es para los desafíos de Fibonacci. ¿Fue útil ¡trabajar como fibonacci con díadas?
Erik the Outgolfer
Oooh - %1+¡: interpolación lineal entre n × F (n) en n y n × F (n-1) + F (n) en n-ε , y subir entre n-ε y n .
Jonathan Allan
@EriktheOutgolfer Bueno, más o menos. Como Jelly no tiene variables, de lo contrario perderías el acceso a los miembros de la secuencia anterior, por lo que tenía sentido implementarlo de esta manera.
Dennis
@ JonathanAllan No estoy seguro de entender. ¿Qué se %1+¡supone que debe hacer?
Dennis
@Dennis erm, quería decir , bueno \ _o_ / ... pero eso es lo que parece hacer con la experimentación: D
Jonathan Allan
5

Mathematica, 32 bytes

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

Función pura que toma un número real no negativo como entrada y devuelve un número real. Si 1~Max~#se reemplazaran por 1, esta sería la definición recursiva estándar de los números de Fibonacci indexados en 0 para argumentos enteros. Pero 1~Max~#es la función lineal por partes correcta para entradas reales entre 0 y 2, y la recursión se encarga del resto. (Dato curioso: ¡cambiar esto a los números de Fibonacci indexados en 1 se puede lograr simplemente cambiando el Maxa a Min!)

Lo más corto que pude obtener con el incorporado es el byte 37 (b=Fibonacci)[i=Floor@#](#-i)+b[i+1]&.

Greg Martin
fuente
3

JavaScript (ES6), 30 bytes

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>

Modificación trivial de la definición de secuencia de Fibonacci recursiva indexada a cero. Puede dar pequeños errores de redondeo para algunas entradas.

ETHproducciones
fuente
Esto es inteligente Pensé que no funcionó.
Leaky Nun
1

Jalea , 17 12 bytes

’Ñ+Ñ
’»0‘ÇỊ?

Pruébalo en línea!

Solución no incorporada.

Explicación

Función auxiliar 1Ŀ

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

Programa 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

Una entrada en el rango de 0 a 1, por lo tanto, se restará saturada a 0, por lo tanto, sumamos 1 para obtener F (0) = F (1) = 1. Se devolverá una entrada en el rango de 1 a 2. Esos casos básicos son suficientes para hacer una típica recursión de Fibonacci y calcular los otros valores a partir de ahí.


fuente
1

Excel, 13712411911310297 Bytes

Enfoque no recursivo / iterativo. (Calcule directamente los enésimos términos) Esto utiliza el índice de uno método de . Agregar +1a lo =TRUNC(B1)cambia a cero indexado.

=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

El fragmento de código está destinado a colocarse comenzando en la celda A1 .

La celda de entrada es B1 . La celda de salida es A1 .

qoou
fuente
1

JavaScript (ES6), 67 64 bytes

Tiene algunos problemas con el redondeo.

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

Intentalo

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

Lanudo
fuente
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]);

Versión en línea

Jörg Hülsermann
fuente
0

Jalea , 13 9 bytes

,‘ḞÆḞḅ%1$

Utiliza la misma indexación que la especificación de desafío.

Pruébalo en línea!

Antecedentes

Según la especificación, tenemos F (n + x) = F (n) + (F (n + 1) - F (n)) x , para n natural y 0 ≤ x <1 . Como F (n + 1) = F (n) + F (n - 1) , esto puede reescribirse como F (n + x) = F (n) + F (n - 1) x .

Además, la indexación utilizada en la especificación de desafío define una función f (n) = F (n + 1) (donde F es la función de Fibonacci habitual, es decir, F (0) = 0 ), por lo que obtenemos la fórmula f (n + x) = F (n + 1) + F (n) x .

Cómo funciona

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

Perl 6 ,  48  38 bytes

48

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

Intentalo

38

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

Intentalo

Expandido:

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
}

( $0y $1es la abreviatura de $/[0]y $/[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
}

Esto fue inspirado por otras soluciones de Python y Javascript

Brad Gilbert b2gills
fuente