Primi elementi di sequenza di Fibonacci


11

C'è una domanda ben nota qui che richiede un generatore di sequenza fibonacci breve (meno caratteri).

Vorrei sapere se qualcuno può generare solo i primi N elementi, della sequenza fibonacci, in uno spazio molto breve. Sto cercando di farlo in Python, ma sono interessato a qualsiasi risposta breve, in qualsiasi lingua. La funzione F (N) genera i primi N elementi della sequenza, o li restituisce come ritorno della funzione o li stampa.

È interessante notare che le risposte di code-golf iniziano con 1 1 2, invece di 0 1 1 2. È una convenzione nel code-golf o nella programmazione in generale? (Wikipedia dice che la sequenza dei fibonacci inizia con zero.)

Esempio Python (primi 5 elementi):

def f(i,j,n):
    if n>0:
        print i;
        f(j,i+j,n-1)
f(1,1,5)

1
Penso che questo sia troppo simile alla domanda collegata. La maggior parte delle soluzioni può essere facilmente modificata per gestire il primo caso.
Hammar,

3
Ovunque abbia visto, i casi di base sono definiti come F_0 = 0, F_1 = 1o equivalentemente F_1 = 1, F_2 = 1. La differenza è se si desidera iniziare la sequenza dall'indice 0 (più comune in programmazione) o 1 (più comune in matematica).
Hammar,

1
E la definizione F_0 = 0, F_1 = 1ha un chiaro vantaggio nella semplicità con la rappresentazione matriciale [[1 1][1 0]]^n = [[F_{n+1} F_n][F_n F_{n-1}]].
Peter Taylor,

1
@Peter: ora che è un buon motivo per preferire l'uno all'altro (per molto tempo preferivo 0, 1 per motivi estetici, ma non credo che quelli che stanno premendo dentro di sé).
dmckee --- ex moderatore gattino

1
Mi rendo conto che questa è una sfida piuttosto vecchia a questo punto, ma nota che hai accettato una risposta che non è la più breve. Poiché si tratta di una competizione di codice golf, la risposta più breve dovrebbe essere quella contrassegnata come accettata.
Alex A.

Risposte:


39

C

Non mi sono preoccupato di contare, ma ecco un esempio divertente:

f(n){return n<4?1:f(--n)+f(--n);}
main(a,b){for(scanf("%d",&b);a++<=b;printf("%d ",f(a)));}

Prova che funziona.


Sono abbastanza orgoglioso di questo: mi sono annoiato, quindi ho riorganizzato il mio codice (con alcune piccole aggiunte) per renderlo dove ogni riga rappresenta un valore nella sequenza di Fibonacci.

                         #                                // 1
                         f                                // 1
                         //                               // 2
                        (n)                               // 3
                       {/**/                              // 5
                      return n                            // 8
                    <2 ? 1:f(--n)                         // 13
                +f(--n); } main(a, b)                     // 21
          {a = 0, b = 0;scanf("%d",&b); for(              // 34
;a < b; a+=1) { int res = f(a); printf("%d ", res); } }   // 55

Prova che funziona.


Bello. 90 caratteri (senza newline). Salva 2 byte: a++<=b-> a++-be return--n<3?1:f(n)+f(n-1). Inoltre puoi evitare scanfse hai bisogno di essere n argc.
ugoren,

Lo adoro! Questo è un ottimo esempio di dove il comportamento indefinito dell'ordine delle due istanze --nnella stessa espressione è irrilevante. Brillante!
Todd Lehman,

A proposito, penso che il tuo 4dovrebbe effettivamente essere un 3. Come attualmente scritto con <4, la sequenza prodotta è 1, 1, 1, 2, 3, 5, 8 ... Questo è uno di troppi 1.
Todd Lehman,

Inoltre, se si desidera gestire correttamente l'elemento zeroth della sequenza, è possibile aggiungere 2 caratteri e modificare il codice inreturn n<3?n>0:f(--n)+f(--n);
Todd Lehman,

6

Haskell (26)

Sorprendentemente, questo è solo un personaggio più lungo della soluzione J.

f = ( `take`s)
S = 0: scanl (+) 1s

Mi rado alcuni personaggi di:

  1. Usando takecome operatore binario;
  2. Usando al scanlposto del verboso zipWith.

Mi ci è voluto letteralmente circa mezz'ora per capire cosa sta succedendo qui, ed sè così elegante, non so come qualcuno potrebbe pensare a una soluzione del genere! Quello che non sapevo è che puoi sriutilizzarlo durante la definizione s. (Sono ancora un principiante =)
flawr

5

Ecco un Python da una riga. Utilizza in virgola mobile, quindi potrebbero essercene alcuni nper i quali non è più preciso.

F=lambda n:' '.join('%d'%(((1+5**.5)/2)**i/5**.5+.5)for i in range(n))

F(n)restituisce una stringa contenente i primi nnumeri di Fibonacci separati da spazi.


Stavo pensando di farlo, ma ho pensato che sarebbe stato troppo lungo. Non ho pensato di usare il pavimento. Molto bella.
Kris Harper

Ah, la formula di Binet. L'ho anche usato ed è accurato, almeno fino al 59 ° numero di fibonacci se conti 0 come primo. Dopo di che i numeri diventano troppo grandi e inizia a usare esponenti.
elssar

70 caratteri, 1 riga, per definire la funzione. + 4 + crlf da invocare. Piuttosto buono!
Warren P,

5

GolfScript, 16 caratteri

~0 1@{.2$+}*;;]`

Esempio di output:

$ ruby golfscript.rb ~/Code/golf/fib.gs <<< "12"
[0 1 1 2 3 5 8 13 21 34 55 89]

4

Perl, 50 caratteri

sub f{($a,$b,$c)=@_;$c--&&say($a)&&f($b,$a+$b,$c)}

4

Scala 71:

def f(c:Int,a:Int=0,b:Int=1):Unit={println(a);if(c>0)f(c-1,b,a+b)};f(9)

stampe

0
1
1
2
3
5
8
13
21
34

Freddo. Non ho ancora suonato con la Scala. Lo proverò stasera a casa.
Warren P,

3

Perl, 29 28 byte

perl -E'say$b+=$;=$b-$;for-pop..--$;' 8
1
1
2
3
5
8
13
21

Spiegazione

Questo si basa sulla $b += $a = $b-$aricorrenza classica che funziona come segue:

  • All'inizio di ogni ciclo $acontiene F(n-2)e $bcontieneF(n)
  • Dopo $a = $b-$a $acontieneF(n-1)
  • Dopo $b += $a $bcontieneF(n+1)

Il problema qui è l'inizializzazione. Il modo classico è $b += $a = $b-$a || 1ma poi la sequenza procede1 2 3 5 ...

Estendendo la sequenza fibonacci a sinistra:

... 5 -3 2 -1 1 0 1 1 2 3 5 ...

vedi che il punto di partenza corretto è $a = -1e$b = 0 . L'inizializzazione di $ a può essere combinata con l'impostazione del loop

Sostituisci infine $acon $;per sbarazzarti dello spazio prima delfor


2

Posso darti una soluzione Python a due righe. Questo li restituirà come un elenco.

f = lambda n: 1 if n < 2 else f(n-1) + f(n-2)
g = lambda m: map(f, range(0,m))

print g(5)

Potresti stamparli aggiungendo un'altra mappa per renderli stringhe e quindi aggiungendo un join, ma questo mi sembra inutile.

Sfortunatamente non so come inserire un lambda ricorsivo map, quindi sono bloccato su due righe.


A cosa serve tornare g(100)? ;)
Mr. Llama,

@GigaWatt Heh, OP non ha mai detto che doveva essere ragionevole. Il tempo di esecuzione asintotico è simile a O (n (1.62) ^ n)?
Kris Harper, il

Ecco un modo in cui puoi (in qualche modo) farlo. Nota che f(n)con n<=0restituisce numeri interi e n>0restituisce elenchi, quindi .. forse non è l'ideale:f = lambda n: map(f, (-x for x in range(0, n))) if n > 0 else -n if n > -2 else f(n+1) + f(n+2)
Dillon Cower

A proposito, ti sei perso il primo 0nella tua risposta. Cambiare fper tornare n if n < 2è una soluzione alternativa. :)
Dillon Cower il

@DC Mi piace la tua soluzione. Abbastanza creativo Sì, ho iniziato il mio con 1, 1 perché è così che l'ho sempre imparato. Ho pensato che cambiarlo fosse abbastanza facile.
Kris Harper,

2

Python (78 caratteri)

Ho usato la formula di Binet per calcolare i numeri di fibonacci -

[(1 + sqrt (5)) ^ N- (1-sqrt (5) ^ n] / [(2 ^ n) sqrt (5)]

Non è così piccola alcune delle altre risposte qui, ma ragazzo è veloce

n=input()
i=1
x=5**0.5
while i<=n:
    print ((1+x)**i-(1-x)**i)/((2**i)*x)
    i+=1

1
Python (12 caratteri): print"11235":)
Joel Cornett,

Puoi radere 2 caratteri eliminando le parentesi 2**i. **hanno una precedenza più alta di*
Joel Cornett,

Il secondo termine nella formula di binet inizia in piccolo e diventa solo più piccolo. Puoi lasciarlo completamente fuori e arrotondare il risultato del primo termine al numero intero più vicino (o aggiungere 0,5 e arrotondare per
difetto

2

schema

Questo è ottimizzato usando la ricorsione della coda:

(define (fib n)
  (let fib ([n n] [a 0] [b 1])
    (if (zero? n) (list a)
        (cons a (fib (- n 1) b (+ a b))))))


2

J, 25 caratteri

Mi rendo conto che le soluzioni J probabilmente non sono ciò che stai cercando, ma eccone comunque una. :-)

0 1(],+/&(_2&{.))@[&0~2-~

Uso:

    0 1(],+/&(_2&{.))@[&0~2-~ 6
0 1 1 2 3 5
    0 1(],+/&(_2&{.))@[&0~2-~ 10
0 1 1 2 3 5 8 13 21 34

Come funziona:

A partire da destra (poiché i programmi J vengono letti da destra a sinistra),

2-~ 6L' ~operatore inverte l'argomento sul verbo, quindi è lo stesso di6-2

Ignorando la sezione tra parentesi per ora, 0 1(...)@[&0~ xprende il verbo tra parentesi e lo esegue xvolte usando la lista 0 1come input - di ~nuovo inverte gli argomenti qui, dandox (...)@[&0 ] 0 1 , il che significa che posso mantenere l'input alla fine della funzione.

All'interno delle parentesi è presente una forcella ],+/&(_2&{.)composta da tre verbi - ], ,e+/&(_2&{.) .

Un fork prende tre verbi a b ce li usa in questo modo: (x a y) b (x c y)dove xe ysono gli argomenti del fork. Il ,è il verbo centro di questa forcella e unisce i risultati x ] ye x +/&(_2&{.) yinsieme.

]restituisce l'argomento sinistro inalterato, quindi x ] yvaluta x.

+/&(_2&{.)prende gli ultimi due elementi dall'elenco indicato (_2&{.)- in questo caso 0 1- e li somma insieme +/(il& s funge solo da colla).

Una volta che il verbo ha funzionato una volta, il risultato viene reinserito per la corsa successiva, generando la sequenza.


2

TI-Basic, 43 caratteri

:1→Y:0→X
:For(N,1,N
:Disp X
:Y→Z
:X+Y→Y
:Z→X
:End

Questo codice può essere inserito direttamente nel programma principale o trasformato in un programma separato a cui fa riferimento il primo.


Questa è la prima soluzione TI-BASIC che abbia mai visto qui che non era da me :) +1
Timtech

Inoltre, nota per le altre persone che i newline non vengono conteggiati qui perché possono essere rimossi.
Timtech,

Ho appena ricevuto una calcolatrice da tastiera TI-92 big-giant-qwerty. Grazie per questo
Warren P

2

APL (33)

{⍎'⎕','←0,1',⍨'←A,+/¯2↑A'⍴⍨9×⍵-2}

Uso:

   {⍎'⎕','←0,1',⍨'←A,+/¯2↑A'⍴⍨9×⍵-2}7
0 1 1 2 3 5 8

Il carattere della casella ⎕ fa parte di APL o un glifo mancante?
Warren P

@WarrenP: Se intendi il 4 ° personaggio da sinistra, si chiama 'quad' e dovrebbe apparire così. Dovrebbe esserci solo una scatola.
Marin


1

Powershell - 35 caratteri

Powershell accetta l' input della pipeline , quindi sono convinto che n |inn | <mycode> non dovrebbe essere in contrasto con il mio conteggio, ma invece è solo una parte dell'avvio di una "funzione" nella lingua.

La prima soluzione presuppone che iniziamo da 0:

%{for($2=1;$_--){($2=($1+=$2)-$2)}}

La seconda soluzione presuppone che possiamo iniziare da 1:

%{for($2=1;$_--){($1=($2+=$1)-$1)}}

Esempio di invocazione: 5 | %{for($2=1;$_--){($1=($2+=$1)-$1)}}

I rendimenti:

1
1
2
3
5

È interessante notare, tentativi di evitare il sovraccarico del for()circuito provocato stesso numero di caratteri: %{$2=1;iex('($1=($2+=$1)-$1);'*$_)}.


1

Python, 43 caratteri

Ecco tre linee fondamentali sostanzialmente diverse che non usano la formula di Binet.

f=lambda n:reduce(lambda(r,a,b),c:(r+[b],a+b,a),'.'*n,([],1,0))[0]
f=lambda n:map(lambda x:x.append(x[-1]+x[-2])or x,[[0,1]]*n)[0]
def f(n):a=0;b=1;exec'print a;a,b=b,a+b;'*n

Non ho mai abusato reducecosì tanto.


1
+1 per reduceabuso
Warren P

1

dc, 32 caratteri:

Questo mostrerà sempre i primi 1, quindi la funzione funziona solo come previsto per N> = 2 .

?2-sn1df[dsa+plarln1-dsn0<q]dsqx

C, 75 caratteri:

Non bello come la risposta accettata, ma più breve e molto più veloce:

main(n,t,j,i){j=0,i=scanf("%d",&n);while(n--)t=i,i=j,printf("%d\n",j+=t);}
Extra:

CL, 64 caratteri:

Uno dei miei segnalibri più usati in questo semestre ha un esempio interessante che è più breve di molti altri qui, ed è solo una semplice invocazione della loopmacro, praticamente solo una frase! Spogliato per tutto lo spazio bianco che potevo:

(loop repeat n for x = 0 then y and y = 1 then(+ x y)collect y)

Abbastanza breve, carino e leggibile! Per leggere l'input, n (compresi gli spazi bianchi circostanti) può essere sostituito con l' (read)aggiunta di 3 caratteri.


... mainprende quattro argomenti?
gatto

1
Ne prende tanti quanti ne dai. In questo caso è solo (ab) usato per definire alcune variabili che verranno usate in seguito :)
daniero

1

FALSO, 28 byte

0 1- 1 10[$][@@$@+$." "@1-]#

Puoi generare -1 usando 1_invece di0 1 -
12Me21

1

Python 2, 38 byte

Un miglioramento rispetto a una soluzione precedentemente pubblicata:

a=b=1
exec'print a;a,b=b,a+b;'*input()

Questo utilizza exece la moltiplicazione di stringhe per evitare loop.

Python 3, 46 byte

Non abbastanza efficiente in Python 3:

a=b=1
exec('print(a);a,b=b,a+b;'*int(input()))

Passando a Python 2 puoi salvare 9 byte: provalo online! Probabilmente puoi aggiungere la versione di Python 2 alla tua risposta.
Stephen,

@Stephen Un buon punto! Aggiornato.
Russell Schwartz,

0

C99, 58 caratteri

La seguente funzione riempie una matrice di numeri interi con i primi nvalori della sequenza di Fibonacci che iniziano con 0.

void f(int*a,int n){for(int p=0,q=1;n--;q+=*a++)*a=p,p=q;}

Testa il cablaggio, prendendo ncome argomento della riga di comando:

#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
     int n = (argc > 1) ? atoi(argv[1]) : 1;
     int a[n];
     f(a, n);
     for (int i = 0; i < n; ++i)
          printf("%d\n", a[i]);
}

0

CoffeeScript, 48

f=(n,i=1,j=1)->(console.log i;f n-1,j,i+j)if n>0

65 in js:

function f(n,i,j){if(n>0)console.log(i),f(n-1,(j=j||1),(i||1)+j)}

0

PHP, 87

function f($n,$a=array(0,1)){echo' '.$a[0];$n>0?f(--$n,array($a[1],array_sum($a))):'';}

Usa array_sume funzione ricorsiva per generare serie.

Per esempio:

 $ php5 fibo.php 9
 0 1 1 2 3 5 8 13 21 34 

0

F #, 123

let f n = Seq.unfold(fun (i,j)->Some(i,(j,i+j)))(0,1)|>Seq.take n
f 5|>Seq.iter(fun x->printfn "%i" x)

0

Scala, 65 caratteri

(Seq(1,0)/:(3 to 9)){(s,_)=>s.take(2).sum+:s}.sorted map println

Questo stampa, ad esempio, i primi 9 numeri di Fibonacci. Per una versione più utilizzabile che prende la lunghezza della sequenza dall'input della console, sono richiesti 70 caratteri:

(Seq(1,0)/:(3 to readInt)){(s,_)=>s.take(2).sum+:s}.sorted map println

Attenzione l'uso di un intervallo limita questo ai valori Int.


0

Q 24

f:{{x,sum -2#x}/[x;0 1]}

Primi numeri di fibonacci


0

Lua, 85 byte

Sto imparando Lua, quindi vorrei aggiungere questa lingua al pool.

function f(x)
    return (x<3) and 1 or f(x-1)+f(x-2)
end
for i=1,io.read() do
    print(f(i))
end

e il tutto ha preso 85 caratteri, con il parametro come argomento della riga di comando. Un altro aspetto positivo è che è facile da leggere.


0

FALSO, 20 caratteri

^1@[1-$][@2ø+$.\9,]#

L'input dovrebbe essere nello stack prima di eseguire questo.


0

Pyt , 3 byte

ř⁻Ḟ

Provalo online!

ř crea un array [1, 2, 3, ..., x]
⁻ Decrementa ogni elemento una volta (poiché Ḟ è 0 indicizzato)
Ḟ per ogni elemento in x lo converte nel suo equivalente fibonacci


0

codice macchina x86 - 379 byte

La versione con intestazioni ELF che segna 484 byte:

00000000: 7f45 4c46 0101 0100 0000 0000 0000 0000  .ELF............
00000010: 0200 0300 0100 0000 c080 0408 3400 0000  ............4...
00000020: 0000 0000 0000 0000 3400 2000 0200 2800  ........4. ...(.
00000030: 0000 0000 0100 0000 0000 0000 0080 0408  ................
00000040: 0000 0000 e401 0000 0010 0000 0500 0000  ................
00000050: 0010 0000 0100 0000 0000 0000 0090 0408  ................
00000060: 0000 0000 0000 0000 0000 1000 0600 0000  ................
00000070: 0010 0000 0000 0000 0000 0000 0000 0000  ................
00000080: 51b9 0090 0408 8801 31c0 ba01 0000 00eb  Q.......1.......
00000090: 0351 89c1 31c0 89c3 43b0 04cd 8031 c099  .Q..1...C....1..
000000a0: 4259 c300 0000 0000 0000 0000 0000 0000  BY..............
000000b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000c0: 31c0 9942 b903 9004 08c6 4101 0ac6 4102  1..B......A...A.
000000d0: 01c6 4103 013a 7103 0f84 ff00 0000 3a71  ..A..:q.......:q
000000e0: 0374 2680 4103 050f b641 036b c008 0041  .t&.A....A.k...A
000000f0: 048a 4104 e887 ffff ff80 6904 30c6 4103  ..A.......i.0.A.
00000100: 0183 e903 3a71 0375 da8a 4104 e86f ffff  ....:q.u..A..o..
00000110: ff3a 7106 0f84 ba00 0000 0fb6 4105 8841  .:q.........A..A
00000120: 060f b641 0788 4105 0fb6 4107 0041 06c6  ...A..A...A..A..
00000130: 4107 003a 7106 0f84 8800 0000 c641 0701  A..:q........A..
00000140: fe49 063a 7106 0f84 7800 0000 c641 0702  .I.:q...x....A..
00000150: fe49 063a 7106 0f84 6800 0000 c641 0703  .I.:q...h....A..
00000160: fe49 063a 7106 0f84 5800 0000 c641 0704  .I.:q...X....A..
00000170: fe49 063a 7106 744c c641 0705 fe49 063a  .I.:q.tL.A...I.:
00000180: 7106 7440 c641 0706 fe49 063a 7106 7434  q.t@.A...I.:q.t4
00000190: c641 0707 fe49 063a 7106 7428 c641 0708  .A...I.:q.t(.A..
000001a0: fe49 063a 7106 741c c641 0709 fe49 063a  .I.:q.t..A...I.:
000001b0: 7106 7410 fe41 08fe 4109 fe49 060f b641  q.t..A..A..I...A
000001c0: 0688 4107 c641 0601 83c1 033a 7106 0f85  ..A..A.....:q...
000001d0: 46ff ffff 3a71 030f 8501 ffff ffb3 0031  F...:q.........1
000001e0: c040 cd80                                .@..

Versione senza testata (quella da classificare):

00000000: 67c6 4101 0a67 c641 0201 67c6 4103 0167  g.A..g.A..g.A..g
00000010: 3a71 030f 842a 0167 3a71 0374 2e67 8041  :q...*.g:q.t.g.A
00000020: 0305 6667 0fb6 4103 666b c008 6700 4104  ..fg..A.fk..g.A.
00000030: 678a 4104 e80d 0167 8069 0430 67c6 4103  g.A....g.i.0g.A.
00000040: 0166 83e9 0367 3a71 0375 d267 8a41 04e8  .f...g:q.u.g.A..
00000050: f200 673a 7106 0f84 df00 6667 0fb6 4105  ..g:q.....fg..A.
00000060: 6788 4106 6667 0fb6 4107 6788 4105 6667  g.A.fg..A.g.A.fg
00000070: 0fb6 4107 6700 4106 67c6 4107 0067 3a71  ..A.g.A.g.A..g:q
00000080: 060f 84a3 0067 c641 0701 67fe 4906 673a  .....g.A..g.I.g:
00000090: 7106 0f84 9200 67c6 4107 0267 fe49 0667  q.....g.A..g.I.g
000000a0: 3a71 060f 8481 0067 c641 0703 67fe 4906  :q.....g.A..g.I.
000000b0: 673a 7106 0f84 7000 67c6 4107 0467 fe49  g:q...p.g.A..g.I
000000c0: 0667 3a71 0674 6167 c641 0705 67fe 4906  .g:q.tag.A..g.I.
000000d0: 673a 7106 7452 67c6 4107 0667 fe49 0667  g:q.tRg.A..g.I.g
000000e0: 3a71 0674 4367 c641 0707 67fe 4906 673a  :q.tCg.A..g.I.g:
000000f0: 7106 7434 67c6 4107 0867 fe49 0667 3a71  q.t4g.A..g.I.g:q
00000100: 0674 2567 c641 0709 67fe 4906 673a 7106  .t%g.A..g.I.g:q.
00000110: 7416 67fe 4108 67fe 4109 67fe 4906 6667  t.g.A.g.A.g.I.fg
00000120: 0fb6 4106 6788 4107 67c6 4106 0166 83c1  ..A.g.A.g.A..f..
00000130: 0367 3a71 060f 8521 ff67 3a71 030f 85d6  .g:q...!.g:q....
00000140: fe00 0000 6651 66b9 7801 0000 6788 0166  ....fQf.x...g..f
00000150: 31c0 66ba 0100 0000 eb05 6651 6689 c166  1.f.......fQf..f
00000160: 31c0 6689 c366 43b0 04cd 8066 31c0 6699  1.f..fC....f1.f.
00000170: 6642 6659 c300 0000 0000 00              fBfY.......

Calcola (possibilmente) numeri di fibonacci.

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.