Interpolazione lineare della sequenza di Fibonacci


20

Il vostro compito è quello di trovare il n ° numero di Fibonacci, ma n non è necessariamente un numero intero.

La sequenza di Fibonacci, indicizzata 0, è la seguente:

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

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

Tuttavia, cosa succede se vogliamo il 2 ° 4 ° numero?

2,4 ° numero è 0,4 volte la differenza tra il 3 ° e 2 ° numeri di Fibonacci più il 2 ° numero di Fibonacci. Quindi, il 2.4 ° numero di Fibonacci è 2 + 0.4 * (3 – 2) = 2.4.

Analogamente, il 6,35 esimo numero di Fibonacci è 13 + 0.35 * (21 – 13) = 15.8.

Il vostro compito è quello di trovare il n ° numero di Fibonacci, in modo tale che n è maggiore o uguale a 0.

Puoi farlo con zero o uno indicizzato, per favore, per favore, dì quale stai usando.

Questo è , quindi vince il codice più corto in byte!

Alcuni altri esempi:

0        1
4.5    6.5
0.7      1
7       21

2
L'operazione che stai facendo qui si chiama "interpolazione lineare". (Ti dispiacerebbe se ho cambiato il titolo del post per riflettere quello?) Sembra avere la proprietà Fibonacci che f (n-2) + f (n-1) = f (n), quindi immagino che sia una ragionevole generalizzazione della sequenza di Fibonacci. (Non sono sicuro che ci sia una generalizzazione standard.)

@ ais523, se pensi che migliorerebbe la domanda, allora sì, puoi cambiare il titolo del post.
Daniel,

Penso che renderà più facile trovare la domanda in futuro se qualcuno fa qualcosa di simile, e rende anche più chiaro di cosa si tratta in, diciamo, nell'elenco "Correlati". Quindi migliorerà la domanda aiutando a trovare i rispondenti nel posto giusto.

2
@ais Sembra che ci sia una generalizzazione della formula Binet: mathworld.wolfram.com/FibonacciNumber.html
Neil,

1
Sebbene il codice golf non debba giustificare la richiesta (immagino), questa sembra un'operazione strana; secondo esso, da allora F_0 = 0e F_2 = 1dovremmo F_1 = (1/2)(F_0 + F_2) = 1/2.
LSpice,

Risposte:


7

Gelatina , 5 byte

_Ḟ1+¡

Questa è una soluzione iterativa senza built-in. Utilizza la stessa indicizzazione delle specifiche della sfida.

Provalo online!

sfondo

Sia f la funzione definita nelle specifiche della sfida e F la funzione di Fibonacci definita come al solito (cioè, con F (0) = 0 ). Per un numero intero non negativo n , abbiamo f (n) = F (n + 1) . Quando 0 ≤ x <1 , la specifica della sfida definisce f (n + x) come f (n) + (f (n + 1) - f (n)) x .

Chiaramente, questo influenza solo i casi di base, ma non la formula ricorsiva, cioè, f (n) = f (n - 1) + f (n - 2) detiene, come avverrebbe in F . Ciò significa che possiamo semplificare la definizione di argomenti non interi al più semplice f (n) = f (n) + f (n - 1) x .

Come altri hanno notato nelle loro risposte, la relazione ricorsiva vale anche per argomenti non interi. Questo è facilmente verificabile, come

prova

Poiché f (0) = f (1) = 1 , f in costante nell'intervallo [0, 1] e F (0 + x) = 1 per tutte le x . Inoltre, f (-1) = F (0) = 0 , quindi f (-1 + x) = f (-1) + (f (0) - f (-1)) x = 0 + 1x = x . Questi casi di base trattano in [-1, 1) , quindi insieme alla formula ricorsiva, completano la definizione di f .

Come funziona

Come prima, n + x sia l'unico argomento del nostro programma monadico.

¡è un rapido , nel senso che consuma alcuni collegamenti alla sua sinistra e li trasforma in un collegamento rapido . ¡in particolare consuma uno o due collegamenti.

  • <F:monad|dyad><N:any>chiama il collegamento N , restituendo r , ed esegue F per un totale di r volte.

  • <nilad|missing><F:monad|dyad>imposta r sull'ultimo argomento della riga di comando (o un input da STDIN in loro assenza) ed esegue F per un totale di r volte.

Poiché 1è un nilad (un collegamento senza argomenti), si applica il secondo caso e verrà eseguito + n volte (un argomento non intero viene arrotondato per difetto). Dopo ogni chiamata a +, l'argomento sinistro del collegamento rapido viene sostituito con il valore restituito e l'argomento destro con il valore precedente dell'argomento sinistro.

Per quanto riguarda l'intero programma, pavimenta l'input, producendo n ; quindi _sottrarre il risultato dall'input, producendo ** x, che diventa il valore restituito.

1+¡quindi chiama - come descritto prima - con l'argomento sinistro 1 = f (0 + x) e l'argomento destro x = f (-1 + x) , che calcola l'output desiderato.


Ah, quanto è utile per le sfide di Fibonacci. Era utile avere un ¡lavoro come fibonacci con diade?
Erik the Outgolfer,

Oooh - %1+¡: interpolazione lineare tra n (n) × F a n ed n × (n-1) F + (n) F a n-ε e accelerare tra n-ε e n .
Jonathan Allan,

@EriktheOutgolfer Bene, più o meno. Dato che Jelly non ha variabili, altrimenti perderebbe l'accesso ai membri della sequenza precedente, quindi ha senso implementarlo in questo modo.
Dennis,

@JonathanAllan Non sono sicuro di aver capito. Cosa %1+¡dovrebbe fare?
Dennis,

@Dennis erm, intendevo , beh \ _o_ / ... ma è quello che sembra fare con la sperimentazione: D
Jonathan Allan

5

Mathematica, 32 byte

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

Funzione pura che prende un numero reale non negativo come input e restituisce un numero reale. Se 1~Max~#venissero sostituiti da 1, questa sarebbe la definizione ricorsiva standard dei numeri di Fibonacci indicizzati 0 per argomenti interi. Ma 1~Max~#è la funzione lineare a tratti corretta per input reali tra 0 e 2 e la ricorsione si occupa del resto. (Curiosità: cambiare questo con i numeri di Fibonacci a 1 indice può essere realizzato semplicemente cambiando Maxin a Min!)

Il più breve che potrei ottenere con il builtin è il 37 byte (b=Fibonacci)[i=Floor@#](#-i)+b[i+1]&.



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>

Modifica fondamentale della definizione di sequenza di Fibonacci ricorsiva a indice zero. Può dare lievi errori di arrotondamento per alcuni input.


Questo è intelligente. Pensavo non funzionasse.
Leaky Nun,

1

Gelatina , 17 12 byte

’Ñ+Ñ
’»0‘ÇỊ?

Provalo online!

Soluzione non integrata.

Spiegazione

Funzione di aiuto 1Ŀ

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

Programma principale

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

Un input compreso tra 0 e 1 verrà quindi sottratto-sottratto a 0, quindi aggiungiamo 1 per ottenere F (0) = F (1) = 1. Un input nell'intervallo da 1 a 2 restituirà se stesso. Quei casi di base sono sufficienti per eseguire una tipica ricorsione di Fibonacci e calcolare gli altri valori da lì.


1

Excel, 137 124 119 113 102 97 byte

Approccio non ricorsivo / iterativo. (Calcola direttamente l'ennesimo termine) Questo utilizza il metodo a un indice . L'aggiunta +1a =TRUNC(B1)cambia in zero indicizzato.

=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

Lo snippet di codice deve essere posizionato a partire dalla cella A1 .

La cella di input è B1 . La cella di output è A1 .


1

JavaScript (ES6), 67 64 byte

Ha alcuni problemi con l'arrotondamento

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

Provalo

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



0

Gelatina , 13 9 byte

,‘ḞÆḞḅ%1$

Questo utilizza la stessa indicizzazione delle specifiche della sfida.

Provalo online!

sfondo

Per la specifica, abbiamo F (n + x) = F (n) + (F (n + 1) - F (n)) x , per n naturale e 0 ≤ x <1 . Poiché F (n + 1) = F (n) + F (n - 1) , questo può essere riscritto come F (n + x) = F (n) + F (n - 1) x .

Inoltre, l'indicizzazione utilizzata nelle specifiche della sfida definisce una funzione f (n) = F (n + 1) (dove F è la solita funzione di Fibonacci, cioè F (0) = 0 ), quindi otteniamo la formula f (n + x) = F (n + 1) + F (n) x .

Come funziona

,‘ḞÆḞḅ%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).

0

Perl 6 ,  48  38 byte

48

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

Provalo

38

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

Provalo

Allargato:

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
}

( $0ed $1è l'abbreviazione di $/[0]e $/[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
}

Questo è stato ispirato da altri Python e Javascript soluzioni


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.