Fibonacci binário


31

Desafio

Você precisa gerar um programa ou função que receba um número inteiro positivo N, calcule os primeiros N termos da sequência de Fibonacci em binário, concatene-o em um único número binário, converta esse número de volta para decimal e, em seguida, gera o decimal como um inteiro.

Por exemplo

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

Você não precisa emitir o ->, apenas o número (por exemplo, se o usuário digitar 4, apenas o resultado 14). As setas são apenas para ajudar a explicar o que o programa deve fazer.

Casos de teste

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

O programa deve ser capaz de produzir até o limite do idioma em uso. Não são permitidas tabelas de pesquisa ou soluções alternativas comuns .

Isso é , então a resposta com o menor número de bytes vence!


1
Foram adicionados casos de teste de 0 a 20 em tio.run/##DYxBCoQwDAC/… . Os nossos agradecimentos a @alephalpha pelo programa.
Nathan Wood

6
Como ainda não foi dito: Bem-vindo ao PPCG! Bom primeiro desafio.
Laikoni 30/03/19

@Laikoni Thanks!
Nathan Wood

Onde exatamente o limite específico do idioma se aplica? Uma função C que retorna um número inteiro de 32 bits seria permitida? Como int32_t binary_concat_Fib(int n), o que limitaria o valor de saída resultante a 2 ^ 31-1. ou seja, você assume que todos os bits concatenados se encaixam em um número inteiro. Ou a função deve funcionar até o ponto em que o maior número de Fibonacci não se encaixa em um número inteiro por si só, para concatenar os bits requer precisão estendida?
Peter Cordes

1
E o "converte em decimal" precisa ser explícito, chamando uma função inteiro-> string ou escrevendo você mesmo? Concatenar os bits em um único inteiro fornece uma representação do valor final. Se bem entendi, a resposta Python de Dennis está retornando um número inteiro, deixando ao chamador transformar esse valor em uma string decimal ou fazer o que quer que seja. Valores inteiros em linguagens de computador que oferecem suporte a operadores de troca de bits são naturalmente binários, não decimais, a menos que sejam armazenados em seqüências de caracteres. Em idiomas sem operadores turnos / bit a bit, nada implica em nenhuma base.
Peter Cordes

Respostas:



10

Geléia ,  7  6 bytes

ḶÆḞBẎḄ

Experimente online!

Quão?

ḶÆḞ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
Brincando com as novas rápidas, descobri que os primeiros n números de Fibonacci também podem ser encontrados usando o Ṛc’SƲƤque poderia ser útil para seqüências semelhantes.
milhas


7

brainfuck , 397 bytes

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

Bem, isso foi divertido!

Pega a entrada ASCII (por exemplo 11), as saídas resultam em ASCII.

Nota: para tentar isso online, defina o tamanho da célula para 32 bits (no lado direito da página da web). Se você não inserir uma entrada, seu navegador poderá travar.

O intérprete não pode manipular entrada de 11e superior porque suporta apenas até 32 bits.

Experimente em copy.sh

Explicação

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

Obtenha entrada decimal e adicione uma (para reduzir o número um por um)

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

Gere números de fibonacci na fita.

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

Configurado para o loop de concatenação binária de entrada


Portanto, as células contêm o valor, começando na primeira posição,

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

Veja estas células:

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

Vou rotular isso:

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

powexiste para encontrar a potência máxima de 2 que é estritamente maior que num. sumé a concatenação de números até agora. caté o poder de 2 que eu precisaria multiplicar numpara concatenar numna frente do sum(para que eu pudesse simplesmente adicionar).


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

Loop: verifique se f_né estritamente menor que pow.

Verdade:

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

Zere o lixo. Em seguida, adicione num* cata sum. Em seguida, carregue o próximo número de Fibonacci (= f_(n-1); se não existir, saia do loop) e defina catcomo cat* pow. Prepare-se para o próximo loop (zere mais lixo, mude o escopo por um).

Falsey:

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

Defina powcomo 2 * pow, restaure num.

]

Repita até que não haja nenhum número de Fibonacci.


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

Lixo limpo. Pegue cada dígito do número resultante e imprima cada um (em ascii).


7

Casca , 7 bytes

ḋṁḋ↑Θİf

Experimente online!

Explicação

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

Bem-vindo ao PPCG! :)
DJMcMayhem

5

Japonês , 9 bytes

ÆMgX ¤Ã¬Í

Executá-lo

Explicação:

Æ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! Bata em mim!
Shaggy

1
@ Shaygy Eu sabia que este seria uma corrida contra você: P
Oliver

4

Pitão, 22 bytes

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

Experimente aqui

Explicação

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 bytes

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

Experimente online!


1
Note que este começa a ficar visivelmente mais lento com entradas acima 200. Demora cerca de 8 segundos para gerar a saída com uma entrada de 1000. (20 segundos se você incluir imprimi-lo)
Brad Gilbert b2gills



2

J, 36 bytes

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

Explicação:

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 bytes

Changelog

  • -13 usando bsr. Obrigado Peter Cordes!
  • -2 zerando os registros commul .

  • -1 usando um loop while em vez de loope push/ pop ecx(crédito Peter Cordes).

Entrada edi, saída 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
Use leapara alternar e adicionar fib2. Além disso, extrair cada bit, um de cada vez, é desnecessário. Use bsr %eax, %ecxpara encontrar o número de bits na representação binária e use um deslocamento por CL / ou para mesclar, como a resposta Python de Dennis está fazendo.
Peter Cordes

1
Você precisa clda contagem de turnos, portanto, pegue seu contador de loop em um registro diferente (como %edi) e use dec %edi / jnz(3 bytes no código de 32 bits, 4 bytes em 64 bits). No código de 32 bits, isso economiza 1 byte total ao descartar o push / pop ecx. Não caia na armadilha de usar loopquando isso dificulta, não é mais fácil. (Sua convenção de chamada já é personalizada, %ebxportanto, não chame sua função main) Você pode retornar no EAX enquanto ainda aproveita o byte de 1 byte xchg, não precisa ser não-padrão se não precisar.
Peter Cordes

1
Você pode substituir o extra inc %ecxda contagem de turnos por um turno extra para a esquerda, à medida que adicionar, usando lea (%eax, %edx, 2), %edx. Neutro em bytes para 32 bits, salva um em x86-64. Mas salva uma instrução.
31818 Peter Cordes #

1
Toda vez que acabo usando o loopcódigo de golfe, me sinto suja. Bem, não exatamente, mas desapontado por não encontrar uma implementação igualmente pequena que evitasse essa instrução lenta; fora do código de golfe, loopé uma das minhas irritações . Eu gostaria que fosse rápido nas CPUs modernas, porque seria muito bom para loops de precisão estendida sem paradas de flag parcial, mas não é e deve ser considerado apenas como uma instrução obscura de otimização de tamanho que torna seu código lento.
Peter Cordes

1
Enfim, bom trabalho. Além de push / pop / loop -> dec / jnz, não vejo nenhuma economia, apenas a aceleração da LEA que é neutra em tamanho de código. Eu sempre me perguntei se alguma vez houve um caso de uso real para o xor/ multruque para zero três registros (Você sempre precisa que muitos zeros?), Mas usando isso como parte da criação de um 1torna mais sensível.
Peter Cordes


2

Haskell , 89 76 75 bytes

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

Versão não destruída:

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
Bem-vindo ao PPCG e Haskell, em particular! Uma maneira mais curta de gerar uma lista infinita de números de Fibonacci é f=0:scanl(+)1f(extraída daqui ). As funções podem ser anônimas, para que você possa abandonar a liderança g=, consulte o nosso Guia de regras de golfe em Haskell .
Laikoni 31/03/19

Obrigado! Isso compensa algumas das funções mais longas usadas. Passei um tempo tentando encontrar uma maneira de implementar a mudança de bits de uma maneira mais concisa, mas não consegui.
user9549915

Você pode substituir $realToFrac ycom .read.show$yum byte
H.PWiz


1

APL + WIN, 55 bytes

Solicita a entrada na tela do número inteiro.

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

A precisão inteira máxima do APL + WIN é 17 e o limite inteiro é da ordem de 10E300, portanto, o número máximo de entrada é 55 e o resultado é: 1.2492739026634838E300



1

Gelatina , 6 bytes

ḶÆḞBFḄ

Experimente online!

gama owered -> n º ÆḞnúmero ibonacci -> a partir de dezembro de Binary -> FLatten -> a partir inary a dezembro


Não entendi essa linguagem, mas achei que a saída nem sempre é correta. por exemplo, Input 10e você receberá um 16024033463, está incorreto (a resposta correta é 250375522).
Guoyang Qin 31/03



1

MATL , 21 bytes

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

Experimente online!

Explicação

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 bytes

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

Experimente online!

Explicação

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 bytes

Experimente online!

Então, eu estava procurando uma maneira de gerar números de fibonacci usando a série, até encontrar isso . Acontece que você pode calcular a série de fibonacci por arredondamento, então tentei o desafio com uma função recursiva.

Achei a abordagem do "arredondamento" muito interessante, também um professor me mostrou isso há um tempo atrás.

Código

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

Explicação

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

Além disso, verifique esta postagem do stackoverflow. A melhor resposta refere-se ao mesmo artigo na Wikipedia.


Maneira interessante de fazê-lo!
Nathan madeira

1

Stax , 9 bytes

ü1∞╓♪εw≤+

Execute e depure-o em staxlang.xyz!

Descompactado (10 bytes) e explicação:

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

Pitão, 27 bytes

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

Suíte de teste

Tradução 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 bytes

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

Suíte de teste

Tradução 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 bytes

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

Programa de teste

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

Suporta até 10, mudar .i(2)para .toLong(2)suportaria até 14, se necessário


0

Python 2, 88 bytes

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 bytes

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

Experimente online!

Salvou alguns bytes concatenando vetores numéricos, não seqüências de caracteres. Caso especial sangrento para 0!


Funções são aceitáveis. Também é muito mais eficiente mudar o resultado deixado pelo número de bits do que se preocupar com vetores numéricos. Veja minha resposta python ou a de Dennis. Isso tem o benefício adicional de lidar com o caso 0.
QWR


@qwr A resposta não é uma função; Estou criando uma função auxiliar porque ela deve estar sapplyem um vetor devido ao fato de ser recursiva. Não pode ser tudo agrupado em uma linha. Como você vê, o programa solicita a entrada do usuário e, em seguida, retorna a resposta. Um byte pode ser salvo criando um atalho para ifelse. E ... nós podemos remover ,""a partir scan, sim.
Andreï Kostyrka 31/03
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.