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.