Éléments de séquence de First-n Fibonacci


11

Il y a une question bien connue ici qui demande un générateur de séquence de fibonacci court (le moins de caractères).

Je voudrais savoir si quelqu'un peut générer les N premiers éléments seulement, de la séquence des fibonacci, dans un espace très court. J'essaie de le faire en python, mais je suis intéressé par une réponse courte, dans n'importe quelle langue. La fonction F (N) génère les N premiers éléments de la séquence, soit les renvoie comme retour de la fonction, soit les imprime.

Il est intéressant de noter que les réponses au code-golf commencent par 1 1 2, au lieu de 0 1 1 2. Est-ce une convention en code-golf ou en programmation en général? (Wikipedia dit que la séquence de fibonacci commence par zéro.).

Exemple Python (5 premiers éléments):

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

1
Je pense que cela est trop similaire à la question liée. La plupart des solutions peuvent être facilement modifiées pour gérer le premier cas n.
hammar

3
Partout où j'ai vu, les cas de base sont définis comme F_0 = 0, F_1 = 1ou de manière équivalente F_1 = 1, F_2 = 1. La différence est de savoir si vous souhaitez démarrer la séquence à l'index 0 (plus courant en programmation) ou 1 (plus courant en mathématiques).
hammar

1
Et la définition F_0 = 0, F_1 = 1présente un avantage certain en termes de simplicité avec la représentation matricielle [[1 1][1 0]]^n = [[F_{n+1} F_n][F_n F_{n-1}]].
Peter Taylor

1
@Peter: Maintenant, c'est une bonne raison de préférer l'un à l'autre (je préférais depuis longtemps 0, 1 pour des raisons esthétiques, mais ne croyez pas que ceux-ci se pressent en eux-mêmes).
dmckee --- chaton ex-modérateur

1
Je me rends compte que c'est un défi assez ancien à ce stade, mais notez que vous avez accepté une réponse qui n'est pas la plus courte. Puisqu'il s'agit d'une compétition de golf à code, la réponse la plus courte devrait être celle qui est marquée comme acceptée.
Alex A.

Réponses:


39

C

Je n'ai pas pris la peine de compter, mais voici un exemple amusant:

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

Preuve que ça marche.


J'en suis assez fier: je me suis ennuyé, j'ai donc réorganisé mon code (avec quelques petits ajouts) pour que chaque ligne représente une valeur dans la séquence 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

Preuve que ça marche.


Agréable. 90 caractères (sans nouvelle ligne). Enregistrez 2 octets: a++<=b-> a++-bet return--n<3?1:f(n)+f(n-1). De plus, vous pouvez éviter scanfsi vous avez besoin de n pour être argc.
ugoren

Aimer! Ceci est un excellent exemple de cas où le comportement indéfini de l'ordre des deux instances de --ndans la même expression n'est pas pertinent. Brillant!
Todd Lehman

Soit dit en passant, je pense 4qu'il devrait y avoir un 3. Comme actuellement écrit avec le <4, la séquence produite est 1, 1, 1, 2, 3, 5, 8 ... C'est un de trop de 1.
Todd Lehman

De plus, si vous souhaitez gérer correctement l'élément zéro de la séquence, vous pouvez ajouter 2 caractères et changer le code enreturn n<3?n>0:f(--n)+f(--n);
Todd Lehman

6

Haskell (26)

Étonnamment, ce n'est un caractère plus que la solution J.

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

Je rase quelques personnages en:

  1. Utilisation takecomme opérateur binaire;
  2. Utiliser scanlau lieu du verbeux zipWith.

Il m'a littéralement fallu environ une demi-heure pour comprendre ce qui se passe ici, et sc'est tellement élégant, je ne sais pas comment on penserait à une solution comme ça! Ce que je ne savais pas, c'est que vous pouvez utiliser à snouveau lors de la définition s. (Je suis toujours un débutant =)
flawr

5

Voici un Python à une ligne. Il utilise des virgules flottantes, il peut donc y en avoir npour lesquelles il n'est plus précis.

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

F(n)renvoie une chaîne contenant les premiers nnombres de Fibonacci séparés par des espaces.


Je pensais à faire ça, mais je pensais que ce serait trop long. Je n'ai pas pensé à utiliser un sol. Très agréable.
Kris Harper

Ah, la formule de Binet. Je l'ai également utilisé et c'est précis, au moins jusqu'au 59e nombre de fibonacci si vous comptez 0 comme premier. Après cela, les nombres deviennent trop grands et il commence à utiliser des exposants.
elssar

70 caractères, 1 ligne, pour définir la fonction. + 4 + crlf pour invoquer. Assez bien!
Warren P

5

GolfScript, 16 caractères

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

Exemple de sortie:

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

4

Perl, 50 caractères

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)

impressions

0
1
1
2
3
5
8
13
21
34

Cool. Je n'ai même pas encore joué avec Scala. Je vais l'essayer ce soir à la maison.
Warren P

3

Perl, 29 28 octets

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

Explication

Ceci est basé sur la $b += $a = $b-$arécurrence classique qui fonctionne comme suit:

  • Au début de chaque boucle $acontient F(n-2)et $bcontientF(n)
  • Après $a = $b-$a $acontientF(n-1)
  • Après $b += $a $bcontientF(n+1)

Le problème ici est l'initialisation. La manière classique est $b += $a = $b-$a || 1mais la séquence continue1 2 3 5 ...

En étendant la séquence des fibonacci vers la gauche:

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

vous voyez que le bon point de départ est $a = -1et $b = 0. L'initialisation de $ a peut être combinée avec la configuration de la boucle

Remplacez enfin $apar $;pour vous débarrasser de l'espace avantfor


2

Je peux vous donner une solution Python à deux lignes. Cela les renverra sous forme de liste.

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)

Vous pouvez le faire imprimer en ajoutant une autre carte pour en faire des chaînes, puis en ajoutant une jointure, mais cela me semble tout simplement inutile.

Malheureusement, je ne sais pas comment mettre un lambda récursif map, donc je suis coincé à deux lignes.


À quoi ça sert g(100)? ;)
M. Llama

@GigaWatt Heh, OP n'a jamais dit que cela devait être raisonnable. Le temps de fonctionnement asymptotique ressemble-t-il à O (n (1.62) ^ n)?
Kris Harper

Voici une façon de procéder (en quelque sorte). Notez f(n)qu'avec des n<=0retours entiers, et n>0renvoie des listes, alors .. peut-être que ce n'est pas idéal: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

Soit dit en passant, vous avez manqué le premier 0dans votre réponse. Changer fpour revenir n if n < 2est une solution de contournement. :)
Dillon Cower

@DC J'aime votre solution. Assez créatif. Oui, j'ai fait commencer le mien par 1, 1 parce que c'est comme ça que je l'ai toujours appris. Je pensais que le changer était assez facile.
Kris Harper

2

Python (78 caractères)

J'ai utilisé la formule de Binet pour calculer les nombres de fibonacci -

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

Ce n'est pas aussi petit que certaines des autres réponses ici, mais mon garçon c'est rapide

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 caractères): print"11235":)
Joel Cornett

Vous pouvez raser 2 caractères en supprimant les parenthèses 2**i. **ont une priorité plus élevée que*
Joel Cornett

Le deuxième terme de la formule de binet commence petit et ne fait que diminuer. Vous pouvez le laisser complètement et arrondir le résultat du premier terme à l'entier le plus proche à la place (ou ajouter 0,5 et arrondir vers le bas)
Ton Hospel

2

Schème

Ceci est optimisé en utilisant la récursivité de queue:

(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 caractères

Je me rends compte que les solutions J ne sont probablement pas ce que vous recherchez, mais en voici une quand même. :-)

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

Usage:

    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

Comment ça fonctionne:

En partant de la droite (car les programmes J sont lus de droite à gauche),

2-~ 6L' ~opérateur inverse l'argument au verbe donc c'est la même chose que6-2

Ignorant la section entre crochets pour l'instant, 0 1(...)@[&0~ x prend le verbe entre crochets et l'exécute xfois en utilisant la liste 0 1comme entrée - ~inverse à nouveau les arguments ici, donnant x (...)@[&0 ] 0 1, ce qui signifie que je peux garder l'entrée à la fin de la fonction.

Entre les crochets se trouve une fourche ],+/&(_2&{.) composée de trois verbes - ], ,et +/&(_2&{.).

Une fourchette prend trois verbes a b cet les utilise comme ceci: (x a y) b (x c y)x et ysont les arguments du fork. Le ,est le verbe central dans cette fourchette et joint les résultats de x ] yet x +/&(_2&{.) yensemble.

]renvoie l'argument de gauche inchangé afin d'être x ] yévalué x.

+/&(_2&{.)prend les deux derniers éléments de la liste donnée (_2&{.)- dans ce cas0 1 - puis les ajoute ensemble +/(les &s agissent simplement comme de la colle).

Une fois que le verbe a fonctionné, le résultat est réinjecté pour la prochaine exécution, générant la séquence.


2

TI-Basic, 43 caractères

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

Ce code peut être directement inséré dans le programme principal, ou transformé en un programme distinct référencé par le premier.


Ceci est la première solution TI-BASIC que j'ai jamais vue ici qui ne soit pas de moi :) +1
Timtech

Notez également pour les autres que les sauts de ligne ne sont pas comptabilisés ici car ils peuvent être supprimés.
Timtech

Je viens de recevoir une calculatrice TI-92 big-giant-qwerty-keyboard. Merci pour celui-ci.
Warren P

2

APL (33)

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

Usage:

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

Le caractère de boîte ⎕ fait-il partie de l'APL ou d'un glyphe manquant?
Warren P

@WarrenP: Si vous voulez dire le 4ème personnage de gauche, cela s'appelle un "quad" et c'est censé ressembler à ça. Il ne devrait y avoir qu'une seule boîte.
marinus


1

Powershell - 35 caractères

Powershell accepte pipeline d' entrée , donc je suis de la croyance que l' n |en n | <mycode>ne devrait pas être contre mon chef d' accusation, mais est plutôt une partie seulement d'initier une « fonction » dans la langue.

La première solution suppose que nous partons de 0:

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

La deuxième solution suppose que nous pouvons commencer à 1:

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

Exemple d'appel: 5 | %{for($2=1;$_--){($1=($2+=$1)-$1)}}

Rendements:

1
1
2
3
5

Fait intéressant, les tentatives pour éviter la surcharge de la for()boucle ont donné lieu dans le même nombre de caractères: %{$2=1;iex('($1=($2+=$1)-$1);'*$_)}.


1

Python, 43 caractères

Voici trois monolignes fondamentalement différentes qui n'utilisent pas la formule 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

Je n'ai jamais abusé reducesi mal.


1
+1 pour reduceabus
Warren P

1

dc, 32 caractères:

En fait, cela affichera toujours les deux premiers 1, donc la fonction ne fonctionne que comme prévu pour N> = 2 .

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

C, 75 caractères:

Pas aussi cool que la réponse acceptée, mais plus court et beaucoup plus rapide:

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

CL, 64 caractères:

L'un de mes signets les plus utilisés ce semestre a un exemple intéressant qui est plus court que bon nombre des autres ici, et c'est juste une invocation directe de la loopmacro - essentiellement une seule déclaration! Dépouillé pour tous les espaces que j'ai pu:

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

Assez court, agréable et lisible! Pour lire l'entrée, n (y compris les espaces blancs environnants) peut être remplacé par (read), en ajoutant 3 caractères.


Est-ce que ... mainprend quatre arguments?
cat

1
Il en faut autant que vous en donnez. Dans ce cas, c'est juste (ab) utilisé pour définir quelques variables qui seront utilisées plus tard :)
daniero

1

FAUX, 28 octets

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

Vous pouvez générer -1 en utilisant 1_plutôt que0 1 -
12Me21

1

Python 2, 38 octets

Une amélioration par rapport à une solution précédemment publiée:

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

Cela utilise execet la multiplication de chaînes pour éviter les boucles.

Python 3, 46 octets

Pas aussi efficace dans Python 3:

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

En passant à Python 2, vous pouvez économiser 9 octets: Essayez-le en ligne! Vous pouvez probablement ajouter la version Python 2 à votre réponse.
Stephen

@Stephen Bon point! Mise à jour.
Russell Schwartz

0

C99, 58 caractères

La fonction suivante remplit un tableau d'entiers avec les premières nvaleurs de la séquence de Fibonacci commençant par 0.

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

Harnais de test, prenant ncomme argument de ligne de commande:

#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 en 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))):'';}

Utilise array_sumet fonction récursive pour générer des séries.

Par exemple:

 $ 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 caractères

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

Cela imprime, par exemple, les 9 premiers numéros de Fibonacci. Pour une version plus utilisable prenant la longueur de séquence de l'entrée de la console, 70 caractères sont requis:

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

Attention, l'utilisation d'une plage limite cela aux valeurs Int.


0

Q 24

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

N premiers nombres de fibonacci


0

Lua, 85 octets

J'apprends Lua donc je voudrais ajouter cette langue à la piscine.

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

et le tout a pris 85 caractères, avec le paramètre comme argument de ligne de commande. Un autre bon point est qu'il est facile à lire.


0

FAUX, 20 caractères

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

L'entrée doit être sur la pile avant d'exécuter cela.


0

Pyt , 3 octets

ř⁻Ḟ

Essayez-le en ligne!

ř crée un tableau [1, 2, 3, ..., x]
⁻ Décrémente chaque élément une fois (car Ḟ est 0 indexé)
Ḟ pour chaque élément de x le convertit en son équivalent fibonacci


0

code machine x86 - 379 octets

La version avec en-têtes ELF totalisant 484 octets:

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

Version sans en-tête (c'est celle à noter):

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

Calcule (éventuellement) nombres de fibonacci.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.