Fibonacci binaire

31

Défi

Vous devez générer un programme ou une fonction qui prend un entier positif N, calcule les premiers N termes de la séquence de Fibonacci en binaire, la concatène en un seul nombre binaire, reconvertit ce nombre en décimal, puis sort la décimale sous la forme d'un entier.

Par exemple

1 -> [0] -> 0 to decimal outputs 0
3 -> [0, 1, 1] -> 011 to decimal outputs 3
4 -> [0, 1, 1, 10] -> 01110 to decimal outputs 14

Vous n'avez pas besoin de sortir le ->, juste le numéro (par exemple si l'utilisateur tape 4, juste de sortir 14). Les flèches sont juste pour aider à expliquer ce que le programme doit faire.

Cas de test

1 -> 0
2 -> 1
3 -> 3
4 -> 14
5 -> 59
6 -> 477
7 -> 7640
8 -> 122253
9 -> 3912117
10 -> 250375522
11 -> 16024033463
12 -> 2051076283353
13 -> 525075528538512
14 -> 134419335305859305
15 -> 68822699676599964537
16 -> 70474444468838363686498
17 -> 72165831136090484414974939
18 -> 147795622166713312081868676669
19 -> 605370868394857726287334099638808
20 -> 4959198153890674493745840944241119317

Le programme doit pouvoir sortir jusqu'à la limite de la langue utilisée. Aucune table de recherche ou solution de contournement commune n'est autorisée.

C'est le , donc la réponse avec le plus petit nombre d'octets gagne!

Nathan Wood
la source
1
Ajout de cas de test de 0 à 20 sur tio.run/##DYxBCoQwDAC/… . Nous remercions @alephalpha pour le programme.
Nathan Wood
6
Comme cela n'a pas encore été dit: Bienvenue chez PPCG! Beau premier défi.
Laikoni
@Laikoni Merci!
Nathan Wood
Où s'applique exactement la limite spécifique à la langue? Une fonction C qui renvoie un entier 32 bits serait-elle autorisée? Comme int32_t binary_concat_Fib(int n), ce qui limiterait la valeur de sortie résultante à 2 ^ 31-1. c'est-à-dire que vous pouvez supposer que tous les bits concaténés tiennent dans un entier. Ou la fonction devrait-elle fonctionner jusqu'au point où le plus grand nombre de Fibonacci ne tient pas seul dans un entier, de sorte que la concaténation des bits nécessite une précision étendue?
Peter Cordes
1
Et le "convertit en décimal" doit-il être explicite, appeler une fonction chaîne entière> ou en écrire une vous-même? La concaténation des bits en un seul entier vous donne une représentation de la valeur finale. Si je comprends bien, la réponse Python de Dennis renvoie un entier, laissant à l'appelant le soin de transformer cette valeur en chaîne décimale ou de faire quoi que ce soit avec. Les valeurs entières dans les langages informatiques qui prennent en charge les opérateurs de décalage binaire sont naturellement binaires, et non décimales, sauf si elles sont stockées dans des chaînes. Dans les langages sans opérateurs shift / bit, rien n'implique de base.
Peter Cordes

Réponses:

11

Python , 64 octets

f=lambda n,a=0,b=1,r=0:n and f(n-1,b,a+b,r<<len(bin(a))-2|a)or r

Essayez-le en ligne!

Dennis
la source
1
Bien, j'essayais juste de réaliser ce style.
Jonathan Allan
10

Gelée ,  7  6 octets

ḶÆḞBẎḄ

Essayez-le en ligne!

Comment?

ḶÆḞBẎḄ - Link: integer, n
Ḷ      - lowered range -> [0,1,2,3,4,5,...,n]
 ÆḞ    - Fibonacci (vectorises) -> [0,1,1,2,3,5...,F(n)]
   B   - to binary (vectorises) -> [[0],[1],[1],[1,0],[1,1],[1,0,1],...,B(F(n))]
    Ẏ  - tighten -> [0,1,1,1,0,1,1,1,0,1,...,B(F(n))[0],B(F(n))[1],...]
     Ḅ - from binary -> answer
Jonathan Allan
la source
1
Jouant avec les nouveaux rapides, j'ai trouvé que les premiers n nombres de Fibonacci peuvent également être trouvés en utilisant Ṛc’SƲƤce qui pourrait être utile pour des séquences similaires.
miles
7

brainfuck , 397 octets

>,[<++++++[->--------<]>>[->++++++++++<]>[-<+>]<<[->+<],]>+[-<<+>>[-[->+<]<<[->+>+<<]<[->+>+<<]>[-<+>]>>[-<<+>>]>]]<<[->+>>>>>+<<<<<<]>[-<+>]>+>>+>>>+<[[->-[<<]>]>[[-]<<<<<<<[->>[-<+>>+<]>[-<+>]<<<]<[->+>>>>>+<<<<<<]>[-<+>]>[-<+>]>[->>[-<+<<+>>>]<[->+<]<]>+>[-]>>+>]<<<<<[[->++>+>++<<<]>[-<+>]<<]>>>]>[-]<<<[-]<<[-]<<->[>++++++++++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>>>]<+[->++++++[-<++++++++>]<.<<<+]

Eh bien, c'était amusant!

Prend l'entrée ASCII (par exemple 11), les sorties résultent en ASCII.

Remarque: pour essayer ceci en ligne, assurez-vous de définir la taille de la cellule sur 32 bits (sur le côté droit de la page Web). Si vous n'entrez pas d'entrée, votre navigateur peut se bloquer.

L'interpréteur ne peut pas gérer les entrées de 11et supérieures car il ne prend en charge que jusqu'à 32 bits.

Essayez-le sur copy.sh

Explication

>,[<++++++[->--------<]>>[->++++++++++<]>[-<+>]<<[->+<],]>+

Obtenez une entrée décimale et ajoutez-en une (pour atténuer les coupures individuelles)

[-<<+>>[-[->+<]<<[->+>+<<]<[->+>+<<]>[-<+>]>>[-<<+>>]>]]

Générez des nombres de fibonacci sur la bande.

<<[->+>>>>>+<<<<<<]>[-<+>]>+>>+>>>+<

Configuration de la boucle de concaténation binaire entrante


Ainsi, les cellules contiennent la valeur, à partir de la première position,

1 | 0 | 1 | 1 | 2 | 3 | 5 | ... | f_n | 0 | 1 | 0 | 1 | 0 | f_n | 1 | 0 | 0 | 0...

Regardez ces cellules:

f_n | 0 | 1 | 0 | 1 | 0 | f_n | 1

Je vais étiqueter ceci:

num | sum | cat | 0 | pow | 0 | num | pow

powest là pour trouver la puissance maximale de 2 strictement supérieure à num. sumest la concaténation des nombres jusqu'à présent. catest la puissance de 2 que j'aurais besoin de multiplier numpour concaténer numdevant le sum(donc je pourrais simplement ajouter).


[[->-[<<]>]>

Boucle: Vérifiez si f_nest strictement inférieur à pow.

Vérité:

[[-]<<<<<<<[->>[-<+>>+<]>[-<+>]<<<]<[->+>>>>>+<<<<<<]>[-<+>]>[-<+>]>[->>[-<+<<+>>>]<[->+<]<]>+>[-]>>+>]

Zéro indésirable. Ajoutez ensuite num* catà sum. Ensuite, chargez le prochain numéro de Fibonacci (= f_(n-1); s'il n'existe pas, quittez la boucle) et réglez catsur cat* pow. Préparez-vous à la prochaine boucle (éliminez plus de fichiers inutiles, modifiez la portée d'un).

Falsey:

<<<<<[[->++>+>++<<<]>[-<+>]<<]

Réglez powsur 2 * pow, restaurez num.

]

Répétez jusqu'à ce qu'il ne reste plus de numéro de Fibonacci.


>[-]<<<[-]<<[-]<<->[>++++++++++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>>>]<+[->++++++[-<++++++++>]<.<<<+]

Déchets propres. Prenez chaque chiffre du nombre résultant et sortez-le chacun (en ascii).

JungHwan Min
la source
7

Coque , 7 octets

ḋṁḋ↑Θİf

Essayez-le en ligne!

Explication

ḋṁḋ↑Θİf                              4
     İf    The Fibonacci numbers     [1,1,2,3,5,8..]
    Θ      Prepends 0                [0,1,1,2,3,5..]
   ↑     Take n elements from list   [0,1,1,2]
  ḋ        Convert to binary digits  [[0],[1],[1],[1,0]]
 ṁ       Map function then concat    [0,1,1,1,0]
ḋ        Convert from base 2         14
Fyr
la source
Bienvenue chez PPCG! :)
DJMcMayhem
5

Japt , 9 octets

ÆMgX ¤Ã¬Í

Exécuter

Explication:

ÆMgX ¤Ã¬Í
Æ     Ã     | Iterate X through the range [0...Input]
 MgX        |   Xth Fibonacci number
     ¤      |   Binary
       ¬    | Join into a string
        Í   | Convert into a base-2 number
Oliver
la source
1
Bah! Battez-moi!
Shaggy
1
@Shaggy Je savais que celui-ci allait être une course contre toi: P
Oliver
4

Pyth, 22 octets

JU2VQ=+Js>2J)is.BM<JQ2

Essayez-le ici

Explication

JU2VQ=+Js>2J)is.BM<JQ2
JU2                       Set J = [0, 1].
   VQ       )             <Input> times...
     =+Js>2J              ... add the last 2 elements of J and put that in J.
                  <JQ     Take the first <input> elements...
               .BM        ... convert each to binary...
              s           ... concatenate them...
             i       2    ... and convert back to decimal.

la source
3

Perl 6 , 38 octets

{:2([~] (0,1,*+*...*)[^$_]>>.base(2))}

Essayez-le en ligne!

Nwellnhof
la source
1
Notez que cela commence à devenir sensiblement plus lent avec des entrées supérieures à 200. Il faut environ 8 secondes pour générer la sortie avec une entrée de 1000. (20 secondes si vous incluez l'impression)
Brad Gilbert b2gills
3

JavaScript (Node.js) , 70 65 58 57 55 octets

  • merci à Shaggy pour avoir réduit 2 octets ('0b + C-0 à' 0b '+ C)
f=(n,a=C=0,b=1)=>--n?f(n,b,a+b,C+=b.toString(2)):'0b'+C

Essayez-le en ligne!

DanielIndie
la source
Vous pouvez abandonner le -0à la fin pour enregistrer encore 2 octets.
Shaggy
2

J, 36 octets

3 :'#.;<@#:"0]2}.(,{:+_2&{)^:y _1 1'

Explication:

3 :'#.;<@#:"0]2}.(,{:+_2&{)^:y _1 1' | Explicit function
                 (,{:+_2&{)^:y _1 1  | Make n fibonacci numbers, with _1 1 leading
              2}.                    | Drop the _1 1
       <@#:"0]                       | Convert each item to binary and box
      ;                              | Unbox and join
    #.                               | Convert back from binary
Bolce Bussiere
la source
2

x86, 37 22 21 octets

Changelog

Entrée edi, sortie edx.

.section .text
.globl main
main:
        mov     $5, %edi            # n = 5

start:
        dec     %edi                # Adjust loop count
        xor     %ebx, %ebx          # b = 0
        mul     %ebx                # a = result = 0
        inc     %ebx                # b = 1

fib:
        add     %ebx, %eax          # a += b
        xchg    %eax, %ebx          # swap a,b
        bsr     %eax, %ecx          # c = (bits of a) - 1
        inc     %ecx                # c += 1
        sal     %cl, %edx           # result >>= c
        add     %eax, %edx          # result += a

        dec     %edi                # n--; do while(n)
        jnz     fib 

        ret

Objdump:

00000005 <start>:
   5:   4f                      dec    %edi
   6:   31 db                   xor    %ebx,%ebx
   8:   f7 e3                   mul    %ebx
   a:   43                      inc    %ebx

0000000b <fib>:
   b:   01 d8                   add    %ebx,%eax
   d:   93                      xchg   %eax,%ebx
   e:   0f bd c8                bsr    %eax,%ecx
  11:   41                      inc    %ecx
  12:   d3 e2                   shl    %cl,%edx
  14:   01 c2                   add    %eax,%edx
  16:   4f                      dec    %edi
  17:   75 f2                   jne    b <fib>
  19:   c3                      ret    
qwr
la source
1
Utilisez leapour déplacer et ajouter dans fib2. De plus, il n'est pas nécessaire d'extraire chaque bit un par un. Utilisez bsr %eax, %ecxpour trouver le nombre de bits dans la représentation binaire, et utilisez un décalage par CL / ou pour fusionner, comme le fait la réponse de Dennis en Python.
Peter Cordes
1
Vous avez besoin clde décomptes, alors prenez votre compteur de boucles dans un registre différent (comme %edi) et utilisez dec %edi / jnz(3 octets en code 32 bits, 4 octets en 64 bits). En code 32 bits, cela permet d'économiser 1 octet au total en supprimant l'ecx push / pop. Ne tombez pas dans le piège de l'utilisation looplorsque cela rend le problème plus difficile, pas plus facile. (Votre convention d'appel est déjà personnalisée, claquante %ebx, alors n'appelez pas votre fonction main) Vous pourriez être en mesure de revenir dans EAX tout en profitant de 1 octet xchg, pas besoin d'être non standard si vous n'en avez pas besoin.
Peter Cordes
1
Vous pouvez remplacer le supplément inc %ecxdu nombre de postes par un décalage supplémentaire vers la gauche au fur et à mesure de votre ajout, à l'aide de lea (%eax, %edx, 2), %edx. Neutre en octets pour 32 bits, enregistre un pour x86-64. Mais enregistre une instruction.
Peter Cordes
1
Chaque fois que je finis par jouer loopau code golf, je me sens sale. Enfin pas tout à fait, mais déçu de ne pas avoir pu trouver une implémentation aussi petite qui évitait cette instruction lente; en dehors du golf de code, loopest l'une de mes bêtes noires . Je souhaite que ce soit rapide sur les processeurs modernes, car ce serait très bien pour les boucles de précision étendue sans décrochage partiel, mais ce n'est pas et devrait être considéré uniquement comme une instruction d'optimisation de taille obscure qui rend votre code lent.
Peter Cordes
1
Bref, beau travail. Autre que push / pop / loop -> dec / jnz, je ne vois aucune économie, juste l'accélération LEA qui est neutre en taille de code. Je me suis toujours demandé s'il y avait jamais eu un vrai cas d'utilisation pour le xor/ multrick à zéro trois registres (avez-vous déjà besoin d'autant de zéros?), Mais l'utiliser dans le cadre de la création d'un 1rend plus sensible.
Peter Cordes
2

Haskell , 89 76 75 octets

f=0:scanl(+)1f
foldr1(\x y->y+x*2*2^floor(logBase 2.read.show$y)).(`take`f)

Version non-golfée:

import Data.Bits

fib = 0:scanl (+) 1 fib

catInt :: Integer -> Integer -> Integer
catInt x y = x' + y where
    position = floor $ succ $ logBase 2 $ realToFrac y
    x' = shift x position

answer :: Integer -> Integer
answer n = foldr1 catInt fib' where
    fib' = take n fib
utilisateur9549915
la source
1
Bienvenue au golf PPCG et Haskell en particulier! Un moyen plus court de générer une liste infinie de nombres de Fibonacci est f=0:scanl(+)1f(tiré d' ici ). Les fonctions peuvent être anonymes, vous pouvez donc supprimer l' interligneg= , consultez notre Guide des règles de golf à Haskell .
Laikoni
Merci! Cela compense certaines des fonctions plus longues utilisées. J'ai passé un certain temps à essayer de trouver un moyen d'implémenter le décalage de bits de manière plus concise, mais j'ai échoué.
user9549915
Vous pouvez remplacer $realToFrac ypar .read.show$ypour un octet
H.PWiz
1

APL + WIN, 55 octets

Invite à saisir un entier à l'écran.

v←b←0 1⋄⍎∊(⎕-2)⍴⊂'v←v,c←+/¯2↑v⋄b←b,((1+⌊2⍟c)⍴2)⊤c⋄'⋄2⊥b

La précision d'entier maximale d'APL + WIN est de 17 et la limite d'entier est de l'ordre de 10E300 donc le nombre d'entrée maximum est de 55 et le résultat est: 1.2492739026634838E300

Graham
la source
1

Gelée , 6 octets

ḶÆḞBFḄ

Essayez-le en ligne!

gamme owered -> n ème ÆḞnombre ibonacci -> de déc à Binaire -> Flatten -> de inary à dec

ChromaticiT
la source
Je n'ai pas compris cette langue mais j'ai pensé que la sortie n'était pas toujours correcte. Par exemple 10, entrez et vous obtiendrez un 16024033463, il est incorrect (la bonne réponse est 250375522).
Guoyang Qin
@AbrahamChin entrée 10retours250375522
Dennis
Réponse équivalente et en double , juste un
avertissement
1

MATL , 21 octets

0li:"yy+]xx&h"@B]&hXB

Essayez-le en ligne!

Explication

0l        % Push 0, then 1 (initial terms of the Fibonacci sequence)
i:"       % Do n times, where n is the input
  yy+     %   Duplicate top two numbers and push their sum
  ]       % End
xx        % Delete the last two results. The stack now contains the
          % first n Fibonacci numbers, starting at 0
&h        % Concatenate all numbers into a row vector
"         % For each
  @       %   Push current number
  B       %   Convert to binary. Gives a vector of 0 and 1
]         % End
&h        % Concatenate all vectors into a row vector
XB        % Convert from binary to decimal. Implicitly display
Luis Mendo
la source
1

J , 25 octets

2(#.;)<@#:@(1#.<:!|.)\@i.

Essayez-le en ligne!

Explication

2(#.;)<@#:@(1#.<:!|.)\@i.  Input: n
                       i.  Range [0, n)
                     \@    For each prefix
                  |.         Reverse
                 !           Binomial coefficient (vectorized)
               <:            Decrement
            1#.              Sum
        #:                   Convert to binary
      <                      Box
    ;                        Link. Join the contents in each box
2 #.                         Convert to decimal from base 2
milles
la source
1

Ajouter ++ , 113 octets

D,f,@@@@*,V$2D+G1+dAppp=0$Qp{f}p
D,k,@,¿1=,1,bM¿
D,g,@,¿1_,1_001${f},1¿{k}
D,w,@,BBbR
D,l,@,ßR€gp€w@0b]@¦+VcG2$Bb

Essayez-le en ligne!

caird coinheringaahing
la source
1

PHP, 124 octets

Essayez-le en ligne!

Donc , je cherchais un moyen de sortie numéros de fibonacci en utilisant la série, jusqu'à ce que je trouve ce . Il s'avère que vous pouvez calculer la série des fibonacci via l'arrondi, j'ai donc essayé le défi avec une fonction récursive.

J'ai trouvé l'approche de "l'arrondi" vraiment intéressante, aussi un professeur me l'a montré il y a quelque temps.

Code

function f($n,$i=0,$b=''){ if($n>$i){$b.=
decbin(round(pow((sqrt(5)+1)/2,$i)/sqrt(5)));f($n,$i+1,$b);}else{echo bindec($b);}}

Explication

function f($n,$i=0,$b=''){           #the function starts with $i=0, our nth-fib number
if($n>$i){                           #it stops once $n (the input) = the nth-fib
    $b.=decbin(                      #decbin returns an integer as bin, concatenates
        round(pow((sqrt(5)+1)/2,$i)/sqrt(5))    
                                       #the formula, basically roundign the expression
        );                           #it returns the (in this case) $i-th fib-number   
    f($n,$i+1,$b);                   #function is called again for the next index
}else{                               #and the current string for fibonacci

    echo bindec($b);                 #"echo" the result, bindec returns the base 10
                                     #value of a base 2 number
}
}

Vérifiez également ce post stackoverflow la meilleure réponse se réfère au même article sur Wikipedia.

Francisco Hahn
la source
Une façon intéressante de le faire!
Nathan Wood
1

Stax , 9 octets

ü1∞╓♪εw≤+

Exécutez-le et déboguez-le sur staxlang.xyz!

Déballé (10 octets) et explication:

vr{|5|Bm|B
v             Decrement integer from input. Stax's Fibonacci sequence starts with 1 :(
 r            Integer range [0..n).
  {    m      Map a block over each value in an array.
   |5           Push nth Fibonacci number.
     |B         Convert to binary.
        |B    Implicit concatenate. Convert from binary. Implicit print.
Khuldraeseth na'Barya
la source
1

Pyth, 27 octets

JU2V-Q2=aJ+eJ@J_2)is.BM<JQ2

Suite de tests

Traduction Python 3:
Q=eval(input())
J=list(range(2))
for i in range(Q-2):
    J.append(J[-1]+J[-2])
print(int(''.join(map("{0:b}".format,J[:Q])),2))

37 octets

J[Z1)W<lJQ=aJ+eJ@J_2)Ig1QZ.?ijkm.BdJ2

Suite de tests

Traduction Python 3:
Q=eval(input())
J=[0,1]
while len(J)<Q:
    J.append(J[-1]+J[-2])
if 1>=Q:
    print(0)
else:
    print(int(''.join(map("{0:b}".format,J)),2))

hakr14
la source
0

Jotlin , 59 octets

g(l(0,1)){l(a.sum(),a[0])}.take(this).j(""){a[0].s(2)}.i(2)

Programme de test

data class Test(val input: Int, val output: Long)

val tests = listOf(
    Test(1, 0),
    Test(2, 1),
    Test(3, 3),
    Test(4, 14),
    Test(5, 59),
    Test(6, 477),
    Test(7, 7640),
    Test(8, 122253),
    Test(9, 3912117),
    Test(10, 250375522)
)
fun Int.r() = g(l(0,1)){l(a.sum(),a[0])}.take(this).j(""){a[0].s(2)}.i(2)

fun main(args: Array<String>) {
    for (r in tests) {
        println("${r.input.r()} vs ${r.output}")
    }
}

Il prend en charge jusqu'à 10, le changement .i(2)en .toLong(2)prendrait en charge jusqu'à 14 si nécessaire

jrtapsell
la source
0

Python 2, 88 octets

def f(n):
 a,b,r=0,1,"0"
 for _ in range(n-1):a,b=b,a+b;r+=bin(a)[2:]
 print int(r,2)
sonrad10
la source
0

R , 244 180 179 octets

i=ifelse;g=function(n)i(n<3,1,g(n-1)+g(n-2))
a=scan(,"");i(a==1,0,sum(2^(which(rev(unlist(sapply(g(2:a-1),function(x)(y=rev(as.numeric(intToBits(x))))[which(!!y)[1]:32]))>0))-1)))

Essayez-le en ligne!

Enregistré quelques octets en concaténant des vecteurs numériques, pas des chaînes. Cas spécial sanglant pour 0!

Andreï Kostyrka
la source
Les fonctions sont acceptables. De plus, il est beaucoup plus efficace de décaler le résultat laissé par le nombre de bits puis de s'embêter avec des vecteurs numériques. Voir ma réponse en python ou celle de Dennis. Cela a l'avantage supplémentaire de gérer le cas 0.
qwr
@qwr La réponse n'est pas une fonction; Je crée une fonction d'aide car elle doit être sapplyassociée à un vecteur car elle est récursive. Il ne peut pas être tout enveloppé dans une seule ligne. Comme vous le voyez, le programme vous invite à saisir les informations de l'utilisateur, puis renvoie la réponse. Un octet peut être enregistré en créant un raccourci pour ifelse. Et ... nous pouvons retirer ,""de scan, oui.
Andreï Kostyrka