Primeiros elementos da sequência de Fibonacci

11

Há uma pergunta bem conhecida aqui que pede um gerador de sequência de fibonacci curto (menos caracteres).

Gostaria de saber se alguém pode gerar apenas os primeiros N elementos, da sequência de fibonacci, em um espaço muito curto. Estou tentando fazer isso em python, mas estou interessado em qualquer resposta curta, em qualquer idioma. A função F (N) gera os primeiros N elementos da sequência, os retorna como o retorno da função ou os imprime.

Curiosamente, parece que as respostas do código-golfe começam com 1 1 2, em vez de 0 1 1 2. Isso é uma convenção em código-golfe ou programação em geral? (A Wikipedia diz que a sequência de fibonacci começa com zero.).

Exemplo de Python (5 primeiros elementos):

def f(i,j,n):
    if n>0:
        print i;
        f(j,i+j,n-1)
f(1,1,5)
Warren P
fonte
11
Eu acho que isso é muito parecido com a questão vinculada. A maioria das soluções pode ser facilmente modificada para lidar com o primeiro caso n.
Hammar
3
Em todos os lugares que eu vi, os casos base são definidos como F_0 = 0, F_1 = 1ou equivalentemente F_1 = 1, F_2 = 1. A diferença é se você deseja iniciar a sequência no índice 0 (mais comum em programação) ou 1 (mais comum em matemática).
Hammar
11
E definir F_0 = 0, F_1 = 1tem um benefício definido na simplicidade com a representação da matriz [[1 1][1 0]]^n = [[F_{n+1} F_n][F_n F_{n-1}]].
Peter Taylor
11
@ Peter: Agora essa é uma boa razão para preferir um ao outro (há muito que prefiro 0, 1 por motivos estéticos, mas não acredito que eles estejam pressionando por si mesmos).
dmckee --- ex-moderador gatinho
11
Sei que esse é um desafio bastante antigo neste momento, mas observe que você aceitou uma resposta que não é a mais curta. Como se trata de uma competição de código de golfe, a resposta mais curta deve ser a que foi marcada como aceita.
Alex A.

Respostas:

39

C

Não se incomodou em contar, mas aqui está um exemplo divertido:

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

Prova de que funciona.


Estou bastante orgulhoso disso: fiquei entediado, então reorganizei meu código (com algumas pequenas adições) para torná-lo onde cada linha representa um valor na sequência de 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 de que funciona.

Mr. Llama
fonte
Agradável. 90 caracteres (sem nova linha). Salve 2 bytes: a++<=b-> a++-be return--n<3?1:f(n)+f(n-1). Além disso, você pode evitar scanfse precisar que n esteja argc.
Ugoren
Adoro! Este é um ótimo exemplo de onde o comportamento indefinido da ordenação das duas instâncias da --nmesma expressão é irrelevante. Brilhante!
Todd Lehman
A propósito, acho que você 4deveria realmente ter um 3. Como está escrito atualmente com o <4, a sequência produzida é 1, 1, 1, 2, 3, 5, 8 ... Esse é um número 1 demais.
Todd Lehman
Além disso, se você deseja manipular o elemento zero da seqüência corretamente, você pode adicionar 2 caracteres e alterar o código parareturn n<3?n>0:f(--n)+f(--n);
Todd Lehman
6

Haskell (26)

Surpreendentemente, esse é apenas um caractere mais longo que a solução J.

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

Eu raspo alguns caracteres por:

  1. Usando takecomo um operador binário;
  2. Usando em scanlvez do detalhado zipWith.
Lambda Fairy
fonte
Levei literalmente cerca de meia hora para entender o que está acontecendo aqui, e sé tão elegante que não sei como alguém pensaria em uma solução como essa! O que eu não sabia é que você pode usar snovamente enquanto define s. (Ainda sou iniciante =) #
flawr
5

Aqui está um Python de uma linha. Ele usa ponto flutuante; portanto, pode haver alguns ndos quais não é mais preciso.

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

F(n)retorna uma string contendo os primeiros nnúmeros de Fibonacci separados por espaços.

Keith Randall
fonte
Eu estava pensando em fazer isso, mas pensei que seria muito longo. Não pensei em usar piso. Muito agradável.
Kris Harper
Ah, a fórmula de Binet. Eu também usei e é preciso, pelo menos até o 59º número de fibonacci, se você contar 0 como o primeiro. Depois disso, os números se tornam muito grandes e começa a usar expoentes.
elssar
70 caracteres, 1 linha, para definir a função. + 4 + crlf para invocar. Muito bom!
Warren P
5

GolfScript, 16 caracteres

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

Exemplo de saída:

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

Perl, 50 caracteres

sub f{($a,$b,$c)=@_;$c--&&say($a)&&f($b,$a+$b,$c)}
Toto
fonte
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)

impressões

0
1
1
2
3
5
8
13
21
34
Usuário desconhecido
fonte
Legal. Ainda nem brinquei com o Scala. Vou tentar hoje à noite em casa.
Warren P
3

Perl, 29 28 bytes

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

Explicação

Isso se baseia na $b += $a = $b-$arecorrência clássica, que funciona da seguinte maneira:

  • No início de cada loop $acontém F(n-2)e $bcontémF(n)
  • Depois $a = $b-$a $acontémF(n-1)
  • Depois $b += $a $bcontémF(n+1)

O problema aqui é a inicialização. O jeito clássico é, $b += $a = $b-$a || 1mas então a sequência continua1 2 3 5 ...

Estendendo a sequência de fibonacci para a esquerda:

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

você vê que o ponto de partida apropriado é $a = -1e $b = 0. A inicialização de $ a pode ser combinada com a configuração do loop

Por fim, substitua $apor $;para se livrar do espaço antes dafor

Ton Hospel
fonte
2

Posso fornecer uma solução Python de duas linhas. Isso os retornará como uma lista.

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)

Você pode imprimi-los adicionando outro mapa para torná-los strings e adicionando uma junção, mas isso me parece desnecessário.

Infelizmente eu não sei como colocar um lambda recursivo map, então estou preso em duas linhas.

Kris Harper
fonte
Para que serve g(100)? ;)
Mr. Llama
@GigaWatt Heh, a OP nunca disse que tinha que ser razoável. O tempo de execução assintótico é algo como O (n (1,62) ^ n)?
Kris Harper
Aqui está uma maneira de você (meio que) fazer isso. Observe que, f(n)com n<=0retornos inteiros e n>0listas de devoluções, então .. talvez não seja o ideal: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 propósito, você perdeu o primeiro 0em sua resposta. Alterar fpara retornar n if n < 2é uma solução alternativa. :)
Dillon Cower
@DC Eu gosto da sua solução. Muito criativo. Sim, eu comecei o meu com 1, 1, porque é assim que eu sempre aprendi. Achei que mudar era fácil o suficiente.
Kris Harper
2

Python (78 caracteres)

Eu usei a fórmula de Binet para calcular os números de fibonacci -

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

Não é tão pequeno, algumas das outras respostas aqui, mas garoto, é rápido

n=input()
i=1
x=5**0.5
while i<=n:
    print ((1+x)**i-(1-x)**i)/((2**i)*x)
    i+=1
elssar
fonte
11
Python (12 caracteres): print"11235":)
Joel Cornett
Você pode raspar 2 caracteres, livrando-se dos parênteses 2**i. **tem precedência maior do que*
Joel Cornett
O segundo termo na fórmula de binet começa pequeno e só fica menor. Você pode deixá-lo completamente e apenas em torno do resultado do primeiro prazo para o número inteiro mais próximo, em vez (ou adicionar 0,5 e para baixo e volta)
Ton Hospel
2

Esquema

Isso é otimizado usando a recursão da cauda:

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

Haskell

fib n = take n f
f = 0:1:zipWith (+) f (tail f)

Prova de que funciona .

lbolla
fonte
Você pode torná-lo uma função usando onde
Hauleth
2

J, 25 caracteres

Sei que as soluções J provavelmente não são o que você procura, mas aqui está uma de qualquer maneira. :-)

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

Como funciona:

Começando pela direita (porque os programas J são lidos da direita para a esquerda),

2-~ 6O ~operador reverte o argumento para o verbo, portanto é o mesmo que6-2

Ignorar a seção entre parênteses por enquanto, 0 1(...)@[&0~ xpega o verbo entre parênteses e executa várias xvezes usando a lista 0 1como entrada - ~novamente inverte os argumentos aqui, fornecendo x (...)@[&0 ] 0 1, o que significa que posso manter a entrada no final da função.

Dentro dos suportes existe um garfo ],+/&(_2&{.)composto por três verbos - ], ,e +/&(_2&{.).

Um garfo pega três verbos a b ce os usa assim: (x a y) b (x c y)onde xe ysão os argumentos do garfo. O ,é o verbo central nesta bifurcação e junta os resultados de x ] ye x +/&(_2&{.) yjuntos.

]retorna o argumento esquerdo inalterado para x ] yavaliar como x.

+/&(_2&{.)leva os dois últimos itens da lista dada (_2&{.)- neste caso 0 1- e, em seguida, adiciona-los juntos +/(o &s apenas agir como cola).

Uma vez que o verbo tenha operado uma vez que o resultado é realimentado para a próxima execução, gerando a sequência.

Gareth
fonte
2

TI-Basic, 43 caracteres

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

Esse código pode ser inserido diretamente no programa principal ou transformado em um programa separado que é referenciado pelo primeiro.

PhiNotPi
fonte
Esta é a primeira solução TI-BASIC que eu já vi aqui que não era por mim :) +1
Timtech
Além disso, observe para outras pessoas que as novas linhas não são contadas aqui porque podem ser removidas.
Timtech
Acabei de comprar uma calculadora de teclado grande-gigante-qwerty da TI-92. Obrigado por este.
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
marinus
fonte
O caractere da caixa é parte do APL ou um glifo ausente?
Warren P
@ WarrenP: Se você quer dizer o quarto caractere da esquerda, isso é chamado de 'quad' e deve ser assim. Deve haver apenas uma caixa.
Marinus
2

Python (55)

a,b=0,1

for i in range(int(input())):a,b=b,a+b;print(b)
Donald Hobson
fonte
1

Powershell - 35 caracteres

Powershell aceita tubulação de entrada , então eu sou da crença de que o n |em n | <mycode>não deve ser contra a minha contagem, mas é apenas uma parte de iniciar uma "função" na língua.

A primeira solução assume que começamos com 0:

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

A segunda solução assume que podemos começar em 1:

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

Exemplo de invocação: 5 | %{for($2=1;$_--){($1=($2+=$1)-$1)}}

Rendimentos:

1
1
2
3
5

Curiosamente, tentativas de evitar a sobrecarga do for()circuito resultou na mesma contagem de caracteres: %{$2=1;iex('($1=($2+=$1)-$1);'*$_)}.

SpellingD
fonte
1

Python, 43 caracteres

Aqui estão três linhas básicas fundamentalmente diferentes que não usam a fórmula de 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

Eu nunca abusei reducetanto.

boothby
fonte
11
+1 por reduceabuso
Warren P
1

dc, 32 caracteres:

Na verdade, isso sempre mostra os dois primeiros 1s, portanto, a função funciona apenas conforme o esperado para N> = 2 .

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

C, 75 caracteres:

Não é tão legal quanto a resposta aceita, mas mais curto e muito mais rápido:

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 caracteres:

Um dos meus favoritos mais usados neste semestre tem um exemplo interessante que é mais curto do que muitos outros aqui, e é apenas uma invocação direta da loopmacro - basicamente apenas uma declaração! Despojei-o para todo o espaço em branco que pude:

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

Muito curto, agradável e legível! Para ler a entrada, n (incluindo os espaços em branco ao redor), pode ser substituído por (read), adicionando 3 caracteres.

daniero
fonte
... mainleva quatro argumentos?
gato
11
É preciso quantos você der. Neste caso é só (ab) usado para definir algumas variáveis que são usadas mais tarde :)
daniero
1

FALSO, 28 bytes

0 1- 1 10[$][@@$@+$." "@1-]#
gato
fonte
Você pode gerar -1 usando em 1_vez de0 1 -
12Me21
1

Python 2, 38 bytes

Uma melhoria em uma solução postada anteriormente:

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

Isso usa uma execmultiplicação de strings para evitar loops.

Python 3, 46 bytes

Não é tão eficiente no Python 3:

a=b=1
exec('print(a);a,b=b,a+b;'*int(input()))
Russell Schwartz
fonte
Ao mudar para o Python 2, você pode salvar 9 bytes: Experimente Online! Você provavelmente pode adicionar a versão Python 2 à sua resposta.
Stephen
@ Stephen Bom ponto! Atualizada.
Russell Schwartz
0

C99, 58 caracteres

A função a seguir preenche uma matriz de números inteiros com os primeiros nvalores da sequência de Fibonacci começando com 0.

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

Arnês de teste, tomando ncomo argumento da linha de 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]);
}
han
fonte
0

CoffeeScript, 48

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

65 em js:

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

PHP, 87

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

Usos array_sum e função recursiva para gerar séries.

Por exemplo:

 $ php5 fibo.php 9
 0 1 1 2 3 5 8 13 21 34 
Karthik
fonte
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)
Smetad Anarkist
fonte
0

Scala, 65 caracteres

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

Isso imprime, por exemplo, os 9 primeiros números de Fibonacci. Para uma versão mais utilizável, utilizando o comprimento da sequência da entrada do console, são necessários 70 caracteres:

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

Cuidado com o uso de um intervalo que limita isso aos valores Int.

Don Mackenzie
fonte
0

Q 24

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

Primeiros n números de fibonacci

sinedcm
fonte
0

Lua, 85 bytes

Estou aprendendo Lua, então gostaria de adicionar esse idioma ao 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 a coisa toda teve 85 caracteres, com o parâmetro como argumento da linha de comando. Outro ponto positivo é que é fácil de ler.

gato
fonte
0

FALSO, 20 caracteres

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

A entrada deve estar na pilha antes de executar isso.

12Me21
fonte
0

Pyt , 3 bytes

ř⁻Ḟ

Experimente online!

ř cria uma matriz [1, 2, 3, ..., x]
Ements diminui cada item uma vez (como Ḟ é 0 indexado)
Ḟ para cada item em x o converte em equivalente de fibonacci

FantaC
fonte
0

código de máquina x86 - 379 bytes

A versão com cabeçalhos ELF com 484 bytes:

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  [email protected].: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                                .@..

Versão sem cabeçalho (que é a única a ser classificada):

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

Calcula (possivelmente) números de fibonacci.

Krzysztof Szewczyk
fonte