二进制斐波那契


31

挑战

您需要生成一个程序或函数,该程序或函数需要一个正整数N,以二进制形式计算斐波那契数列的前N个项,将其连接为单个二进制数,将该数字转换回十进制,然后将十进制输出为整数。

例如

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

您无需输出->,只需输出数字(例如,如果用户输入4,则仅输出14)。箭头仅用于帮助解释程序必须执行的操作。

测试用例

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

该程序必须能够输出所使用语言的限制。不允许使用查找表或常见的解决方法

这是,因此最短字节数的答案会获胜!


1
tio.run/##DYxBCoQwDAC/…添加了从0到20的测试用例。感谢该程序的@alephalpha。
内森·伍德

6
尚未有人说:欢迎来到PPCG!不错的第一个挑战。
Laikoni

@Laikoni谢谢!
内森·伍德

特定语言的限制到底在哪里适用?返回32位整数的C函数是否被允许?像一样int32_t binary_concat_Fib(int n),它将结果输出值限制为2 ^ 31-1。即,您假设所有串联的位都适合整数。还是该函数工作到最大斐波那契数本身不适合整数的程度,所以将位连接起来可以提高精度?
彼得·科德斯

1
并且“转换为十进制”是否必须明确,调用integer-> string函数或自己编写?将这些位连接成一个整数可以表示最终值。如果我理解正确,Dennis的Python回答将返回一个整数,将其留给调用方将其转换为十进制字符串或使用它进行任何操作。支持位移运算符的计算机语言中的整数值自然是二进制而不是十进制,除非它们存储在字符串中。在没有移位/按位运算符的语言中,没有任何含义表示基础。
彼得·科德斯

Answers:



10

果冻 7  6 字节

ḶÆḞBẎḄ

在线尝试!

怎么样?

ḶÆḞ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
在使用新的快捷方式时,我发现还可以找到前n个斐波那契数Ṛc’SƲƤ,这对于类似的序列很有用。
英里


7

brainfuck,397个字节

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

好吧,那很有趣!

接受ASCII输入(例如11),以ASCII输出结果。

注意:要在线尝试此操作,请确保将单元格大小设置为32位(在网页右侧)。 如果不输入输入,则浏览器可能会崩溃。

解释器不能处理11或更高的输入,因为它最多支持32位。

在copy.sh上尝试

说明

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

获取十进制输入并加一(以减轻不合一的影响)

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

在磁带上生成斐波那契数。

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

设置传入的二进制串联循环


因此,单元格包含从第一个位置开始的值,

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

查看以下单元格:

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

我将其标记为:

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

pow在这里找到2的最大幂严格大于numsum到目前为止是数字的串联。cat是2的幂,我需要乘以2 num才能num在前面串联sum(所以我可以简单地加上)。


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

循环:检查是否f_n严格小于pow

真相:

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

零垃圾。然后,将num* 添加catsum。接下来,加载下一个斐波纳契数(= f_(n-1);如果不存在,则退出循环)并将其设置catcat* pow。准备下一个循环(将更多垃圾归零,将作用域移一)。

虚假:

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

设置pow为2 * pow,还原num

]

重复直到没有斐波那契数为止。


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

清洁垃圾。取结果数字的每个数字并输出(以ASCII表示)。


7

外壳,7个字节

ḋṁḋ↑Θİf

在线尝试!

说明

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

欢迎来到PPCG!:)
DJMcMayhem

5

Japt,9个字节

ÆMgX ¤Ã¬Í

运行

说明:

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

1
呸! 击败我吧!
毛茸茸的

1
@Shaggy我知道这将是一场与你的比赛:P
奥利弗,

4

Pyth,22个字节

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

在这里尝试

说明

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.




2

J,36字节

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

说明:

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

86,37 22 21字节

变更日志

  • -13通过使用 bsr。谢谢彼得·科德斯!
  • -2通过将寄存器清零mul

  • 通过使用while循环而不是loopand push/ 来返回-1 pop ecx(信贷Peter Cordes)。

输入输入edi,输出输入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
用于lea在fib2中进行移位和添加。另外,一次提取每个位也是不必要的。用bsr %eax, %ecx找到的二进制表示的位数,并使用CL移进/或合并,像丹尼斯的Python的回答是干。
彼得·科德斯

1
您需要cl进行移位计数,因此请将循环计数器放在不同的reg中(例如%edi),然后使用dec %edi / jnz(32位代码中3个字节,64位中4个字节)。在32位代码中,通过删除push / pop ecx总共节省了1个字节。loop当问题变得更难而不容易时,不要陷入使用陷阱。(您的调用约定已经是自定义,破坏性的了%ebx,所以不要调用您的函数main)您可以在仍使用1字节的情况下以EAX返回,xchg如果不需要,则不需要非标准。
彼得·科德斯

1
您可以inc %ecx使用添加一个额外的左移,以替换多余的移位计数lea (%eax, %edx, 2), %edx。中性位(以字节为单位)表示32位,x86-64为1。但是保存一条指令。
彼得·科德斯

1
每次我最终使用loop代码高尔夫时,我都会感到肮脏。很好,但令我失望的是,我找不到能够避免这种缓慢指令的同样小的实现;除了打高尔夫,loop是我的宠儿之一。我希望它在现代CPU上速度很快,因为它对于没有部分标志停顿的扩展精度循环非常有用,但是并非如此,并且应该仅将其视为晦涩的大小优化指令,这会使您的代码变慢。
彼得·科德斯

1
无论如何,不​​错。除了push / pop / loop-> dec / jnz之外,我看不到任何节省,只是LEA加速在代码大小上是中立的。我一直想知道xor/ mul技巧是否曾经有过真正的用例来将三个寄存器归零(您是否需要那么多的零?),但是将其作为创建一个的一部分1使它变得更加明智。
彼得·科德斯


2

Haskell89 76 75字节

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

非高尔夫版本:

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
欢迎来到PPCG,尤其是Haskell高尔夫!生成无限数量的斐波那契数的更短方法是f=0:scanl(+)1f(从此处获取)。函数可以是匿名的,因此您可以删除前导g=,请参阅Haskell中的Ggolfing规则指南
Laikoni '18

谢谢!这补偿了一些较长的功能。我花了一段时间试图找到一种以更简洁的方式实现移位的方法,但没有成功。
user9549915 '18

您可以替换$realToFrac y.read.show$y一个字节
H.PWiz


1

APL + WIN,55个字节

提示屏幕输入整数。

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

APL + WIN的最大整数精度为17,整数限制为10E300的量级,因此最大输入数为55,结果为:1.2492739026634838E300




1

MATL,21字节

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

在线尝试!

说明

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.

Try it online!

Explanation

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

Try it online!

So I was looking for a way to output fibonacci numbers using the series, until I found this. It turns out you can calculate the fibonacci series via rounding, so I tried the challenge with a recursive function.

I found the approach of "rounding" really interesting, also a professor showed me this a while ago.

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

Explanation

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

Also check this stackoverflow post the best answer refers to the same article on Wikipedia.


Interesting way to do it!
Nathan Wood

1

Stax, 9 bytes

ü1∞╓♪εw≤+

Run and debug it at staxlang.xyz!

Unpacked (10 bytes) and explanation:

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 bytes

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

Test suite

Python 3 translation:
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

Test suite

Python 3 translation:
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)

Test Program

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

It supports up to 10, changing .i(2) for .toLong(2) would support up to 14 if needed


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

Try it online!

Saved some bytes by concatenating numeric vectors, not strings. Bloody special case for 0!


Functions are acceptable. Also it is much more efficient to shift the result left by the number of bits then to bother with numeric vectors. See my or Dennis's python answer. This has the added benefit of handling the 0 case.
qwr


@qwr The answer is not a function; I am creating a helper function because it must be sapply’d to a vector due to the fact that it is recursive. It cannot be all wrapped into one line. As you see, the programme prompts for user’s input and then returns the answer. One byte can be saved by creating a shortcut for ifelse. And... we can remove ,"" from scan, yes.
Andreï Kostyrka
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.