Fibonacci binari


31

Sfida

È necessario generare un programma o una funzione che accetta un numero intero positivo N, calcola i primi N termini della sequenza di Fibonacci in binario, lo concatena in un singolo numero binario, converte quel numero in decimale e quindi restituisce il decimale come un numero intero.

Per esempio

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

Non è necessario emettere il ->, solo il numero (ad es. Se l'utente digita 4, solo l'output 14). Le frecce servono solo a spiegare cosa deve fare il programma.

Casi 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

Il programma deve essere in grado di produrre fino al limite della lingua in uso. Non sono consentite tabelle di ricerca o soluzioni alternative comuni .

Questo è , quindi vince la risposta con il minor numero di byte!


1
Aggiunti casi di test da 0 a 20 da tio.run/##DYxBCoQwDAC/… . Ringraziamo @alephalpha per il programma.
Nathan Wood,

6
Come non è stato ancora detto: benvenuto in PPCG! Bella prima sfida.
Laikoni,

@Laikoni Grazie!
Nathan Wood,

Dove si applica esattamente il limite specifico della lingua? Sarebbe consentita una funzione C che restituisce un numero intero a 32 bit? Come int32_t binary_concat_Fib(int n), che limiterebbe il valore di output risultante a 2 ^ 31-1. vale a dire che si assume che tutti i bit concatenati rientrino in un numero intero. O la funzione dovrebbe funzionare fino al punto in cui il più grande numero di Fibonacci non si adatta a un intero da solo, quindi concatenare i bit richiede una precisione estesa?
Peter Cordes,

1
E i "convertiti in decimali" devono essere espliciti, chiamando una funzione intera-> stringa o scrivendone una tu? Concatenare i bit in un singolo numero intero ti dà una rappresentazione del valore finale. Se ho capito bene, la risposta Python di Dennis sta restituendo un numero intero, lasciando al chiamante la possibilità di trasformare quel valore in una stringa decimale o fare qualunque cosa con esso. I valori interi in linguaggi informatici che supportano gli operatori bit-shift sono naturalmente binari, non decimali, a meno che non siano memorizzati in stringhe. Nelle lingue senza turni / operatori bit a bit, nulla implica alcuna base.
Peter Cordes,

Risposte:



10

Gelatina ,  7  6 byte

ḶÆḞBẎḄ

Provalo online!

Come?

ḶÆḞ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

1
Facendo casino con i nuovi quick, ho scoperto che i primi n numeri di Fibonacci possono anche essere trovati usando Ṛc’SƲƤquale potrebbe essere utile per sequenze simili.
miglia


7

Brainfuck , 397 byte

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

Beh, è ​​stato divertente!

Accetta l'ingresso ASCII (ad es. 11), Le uscite producono ASCII.

Nota: per provare online, assicurati di impostare la dimensione della cella su 32 bit (sul lato destro della pagina web). Se non si immette un input, il browser potrebbe bloccarsi.

L'interprete non può gestire l'input di 11e superiore perché supporta solo fino a 32 bit.

Provalo su copy.sh

Spiegazione

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

Ottieni input decimale e aggiungine uno (per mitigare off-by-one)

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

Genera numeri di fibonacci sul nastro.

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

Configurato per il loop di concatenazione binario in entrata


Quindi le celle contengono il valore, a partire dalla prima posizione,

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

Guarda queste celle:

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

Etichetta questo:

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

powè lì per trovare la potenza massima di 2 che è strettamente maggiore di num. sumè la concatenazione di numeri finora. catè il potere di 2 che avrei bisogno di moltiplicare numper concatenare numdi fronte al sum(quindi sarei in grado di aggiungere semplicemente).


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

Loop: controlla se f_nè strettamente inferiore a pow.

Truthy:

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

Azzera spazzatura. Quindi, aggiungi num* cata sum. Successivamente, carica il prossimo numero di Fibonacci (= f_(n-1); se non esiste, esci dal loop) e imposta catsu cat* pow. Preparati per il ciclo successivo (azzera più spazzatura, sposta l'ambito di uno).

Falsey:

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

Impostare powsu 2 * pow, ripristinare num.

]

Ripetere fino a quando non è rimasto alcun numero di Fibonacci.


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

Immondizia pulita. Prendi ogni cifra del numero risultante e stampa ciascuna (in ascii).


7

Buccia , 7 byte

ḋṁḋ↑Θİf

Provalo online!

Spiegazione

ḋṁḋ↑Θİ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

Benvenuti in PPCG! :)
DJMcMayhem

5

Japt , 9 byte

ÆMgX ¤Ã¬Í

Eseguirlo

Spiegazione:

ÆMgX ¤Ã¬Í
Æ     Ã     | Iterate X through the range [0...Input]
 MgX        |   Xth Fibonacci number
     ¤      |   Binary
       ¬    | Join into a string
        Í   | Convert into a base-2 number

1
Bah! Sconfiggimi!
Shaggy,

1
@Shaggy Sapevo che questa sarebbe stata una gara contro di te: P
Oliver

4

Pyth, 22 byte

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

Provalo qui

Spiegazione

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.

3

Perl 6 , 38 byte

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

Provalo online!


1
Si noti che questo inizia a diventare notevolmente più lento con input superiori a 200. Sono necessari circa 8 secondi per generare l'output con un input di 1000. (20 secondi se si include la stampa)
Brad Gilbert b2gills



2

J, 36 byte

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

Spiegazione:

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

2

x86, 37 22 21 byte

changelog

  • -13 usando bsr. Grazie Peter Cordes!
  • -2 azzerando i registri conmul .

  • -1 utilizzando un ciclo while anziché loope push/ pop ecx(credito Peter Cordes).

Ingresso in edi, uscita in 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    

1
Utilizzare leaper spostare e aggiungere in fib2. Inoltre, non è necessario estrarre ogni bit uno alla volta. Usa bsr %eax, %ecxper trovare il numero di bit nella rappresentazione binaria e usa uno spostamento di CL / o per unire, come sta facendo la risposta Python di Dennis.
Peter Cordes,

1
Hai bisogno cldi conteggi di turni, quindi prendi il tuo contatore di loop in un reg (like %edi) diverso e usa dec %edi / jnz(3 byte nel codice a 32 bit, 4 byte nel 64-bit). Nel codice a 32 bit, ciò consente di risparmiare 1 byte totale dall'eliminazione del push / pop ecx. Non cadere nella trappola dell'utilizzo loopquando rende il problema più difficile, non più semplice. (La tua convenzione di chiamata è già personalizzata, altera %ebx, quindi non chiamare la tua funzione main) Potresti essere in grado di tornare in EAX pur sfruttando 1 byte xchg, non è necessario essere non standard se non è necessario.
Peter Cordes,

1
È possibile sostituire il extra inc %ecxdel conteggio dei turni con un ulteriore spostamento a sinistra mentre si aggiunge, utilizzando lea (%eax, %edx, 2), %edx. Neutro in byte per 32 bit, ne salva uno per x86-64. Ma salva un'istruzione.
Peter Cordes,

1
Ogni volta che finisco per usare il loopcodice golf, mi sento sporco. Beh, non del tutto, ma deluso dal fatto che non riuscivo a trovare un'implementazione altrettanto piccola che evitasse quell'istruzione lenta; al di fuori del codice golf, loopè uno dei miei animali domestici . Ho voluto che fosse veloce su CPU moderne, perché sarebbe molto bello per i loop esteso precisione senza bancarelle parziale di bandiera, ma non è e deve essere considerato solo come istruzione ottimizzazione dimensioni oscuro che rende il codice lento.
Peter Cordes,

1
Comunque, bel lavoro. A parte push / pop / loop -> dec / jnz, non vedo alcun risparmio, solo lo speedup LEA che è neutro nella dimensione del codice. Mi ero sempre chiesto se ci fosse mai stato un vero caso d'uso per il xor/ multrick per azzerare tre registri (hai mai bisogno di tanti zero?), Ma usarlo come parte della creazione di un 1rende più sensato.
Peter Cordes,


2

Haskell , 89 76 75 byte

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

Versione non golfata:

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

1
Benvenuti in particolare al golf PPCG e Haskell! Un modo più breve per generare un elenco infinito di numeri di Fibonacci è f=0:scanl(+)1f(preso da qui ). Le funzioni possono essere anonime, quindi puoi lasciar perdere il comandog= , consulta la nostra Guida alle regole di Ggolfing in Haskell .
Laikoni,

Grazie! Ciò compensa alcune delle funzioni più lunghe utilizzate. Ho trascorso un po 'di tempo a cercare un modo per implementare il bit-shifting in un modo più conciso, ma sono arrivato breve.
user9549915

Puoi sostituirlo $realToFrac ycon .read.show$yper un byte
H.Pwiz


1

APL + WIN, 55 byte

Richiede l'immissione dello schermo di un numero intero.

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

La precisione massima dell'intero di APL + WIN è 17 e il limite intero è dell'ordine di 10E300 quindi il numero massimo di input è 55 e il risultato è: 1.2492739026634838E300



1

Gelatina , 6 byte

ḶÆḞBFḄ

Provalo online!

gamma owered -> n esimo ÆḞnumero ibonacci -> da dicembre a Bfabbrica di alcune componenti -> Flatten -> da fabbrica di alcune componenti a dicembre


Non ho capito questo linguaggio ma ho pensato che l'output non fosse sempre corretto. es. inserisci 10e otterrai un 16024033463, è errato (la risposta corretta è 250375522).
Guoyang Qin



1

MATL , 21 byte

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

Provalo online!

Spiegazione

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

1

J , 25 byte

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

Provalo online!

Spiegazione

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



1

PHP, 124 byte

Provalo online!

Quindi stavo cercando un modo per produrre numeri di fibonacci usando la serie, fino a quando non ho trovato questo . Si scopre che è possibile calcolare la serie di fibonacci tramite arrotondamento, quindi ho provato la sfida con una funzione ricorsiva.

Ho trovato molto interessante l'approccio del "arrotondamento", anche un professore me lo ha mostrato poco fa.

Codice

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);}}

Spiegazione

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

Controlla anche questo post di StackOverflow, la migliore risposta si riferisce allo stesso articolo su Wikipedia.


Modo interessante per farlo!
Nathan Wood,

1

Stax , 9 byte

ü1∞╓♪εw≤+

Eseguilo e esegui il debug su staxlang.xyz!

Spacchettato (10 byte) e spiegazione:

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.


1

Pyth, 27 byte

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

Suite di test

Traduzione di 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 byte

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

Suite di test

Traduzione di 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))



0

Jotlin , 59 byte

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

Programma di 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}")
    }
}

Supporta fino a 10, cambiare .i(2)per .toLong(2)supportare fino a 14 se necessario


0

Python 2, 88 byte

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)

0

R , 244 180 179 byte

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

Provalo online!

Salvati alcuni byte concatenando i vettori numerici, non le stringhe. Caso sanguinante speciale per 0!


Le funzioni sono accettabili Inoltre è molto più efficiente spostare il risultato lasciato dal numero di bit, quindi disturbarsi con i vettori numerici. Vedi la mia o la risposta del pitone di Dennis. Ciò ha l'ulteriore vantaggio di gestire il caso 0.
qwr


@qwr La risposta non è una funzione; Sto creando una funzione di supporto perché deve essere sapplydi un vettore a causa del fatto che è ricorsiva. Non può essere tutto avvolto in una riga. Come vedi, il programma richiede l'immissione dell'utente e quindi restituisce la risposta. È possibile salvare un byte creando un collegamento per ifelse. E ... possiamo rimuovere ,""da scan, sì.
Andreï Kostyrka,
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.