Fibre nhị phân


31

Thử thách

Bạn cần tạo một chương trình hoặc hàm lấy số nguyên dương N, tính toán các số hạng N đầu tiên của chuỗi Fibonacci trong nhị phân, ghép nó thành một số nhị phân duy nhất, chuyển đổi số đó thành số thập phân và sau đó xuất ra số thập phân dưới dạng số thập phân số nguyên.

Ví dụ

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

Bạn không cần phải xuất số ->, chỉ là số (ví dụ: nếu người dùng nhập 4, chỉ cần xuất 14). Các mũi tên chỉ để giúp giải thích những gì chương trình phải làm.

Các trường hợp thử nghiệm

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

Chương trình phải có khả năng xuất ra đến giới hạn của ngôn ngữ đang sử dụng. Không có bảng tra cứu hoặc giải pháp chung cho phép.

Đây là , vì vậy câu trả lời có số byte ngắn nhất sẽ thắng!


1
Đã thêm các trường hợp kiểm tra từ 0 đến 20 từ tio.run/##DYxBCoQwDAC/ . Tín dụng cho @alephalpha cho chương trình.
Nathan Wood

6
Như chưa nói: Chào mừng bạn đến với PPCG! Thử thách đầu tiên tốt đẹp.
Laikoni

@Laikoni Cảm ơn!
Nathan Wood

Trường hợp chính xác giới hạn ngôn ngữ cụ thể áp dụng? Hàm C trả về số nguyên 32 bit có được phép không? Giống như int32_t binary_concat_Fib(int n), sẽ giới hạn giá trị đầu ra kết quả là 2 ^ 31-1. tức là bạn có thể giả sử tất cả các bit được nối phù hợp với một số nguyên. Hoặc hàm có nên hoạt động đến điểm mà số Fibonacci lớn nhất không tự khớp với một số nguyên hay không, do đó, việc ghép các bit có độ chính xác mở rộng?
Peter Cordes

1
Và "chuyển đổi thành thập phân" có phải rõ ràng không, gọi hàm số nguyên-> chuỗi hoặc tự viết một hàm? Ghép các bit thành một số nguyên duy nhất cung cấp cho bạn một đại diện của giá trị cuối cùng. Nếu tôi hiểu chính xác, câu trả lời Python của Dennis đang trả về một số nguyên, để lại cho người gọi để biến giá trị đó thành một chuỗi thập phân hoặc làm bất cứ điều gì với nó. Các giá trị số nguyên trong các ngôn ngữ máy tính hỗ trợ các toán tử dịch chuyển bit là nhị phân tự nhiên, không phải là số thập phân, trừ khi chúng được lưu trữ trong chuỗi. Trong các ngôn ngữ không có toán tử dịch chuyển / bitwise, không có gì ngụ ý bất kỳ cơ sở nào.
Peter Cordes

Câu trả lời:



10

Thạch ,  7  6 byte

ḶÆḞBẎḄ

Hãy thử trực tuyến!

Làm sao?

ḶÆḞ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
Loay hoay với những bước nhanh mới, tôi thấy rằng n số Fibonacci đầu tiên cũng có thể được tìm thấy bằng cách sử dụng Ṛc’SƲƤcó thể hữu ích cho các chuỗi tương tự.
dặm


7

Brainfuck , 397 byte

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

Vâng, đó là niềm vui!

Đưa đầu vào ASCII (ví dụ 11), kết quả đầu ra trong ASCII.

Lưu ý: để thử trực tuyến này, hãy đảm bảo bạn đặt kích thước ô là 32 bit (ở bên phải trang web). Nếu bạn không nhập dữ liệu đầu vào, trình duyệt của bạn có thể bị sập.

Trình thông dịch không thể xử lý đầu vào 11và cao hơn vì nó chỉ hỗ trợ tối đa 32 bit.

Hãy thử nó trên copy.sh

Giải trình

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

Nhận đầu vào thập phân và thêm một (để giảm thiểu từng cái một)

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

Tạo số Wikipedia trên băng.

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

Thiết lập cho vòng lặp nhị phân đến


Vì vậy, các ô chứa giá trị, bắt đầu từ vị trí đầu tiên,

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

Nhìn vào các tế bào này:

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

Tôi sẽ dán nhãn này:

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

powcó để tìm ra sức mạnh tối đa của 2 mà lớn hơn nhiều num. sumlà sự kết hợp của các con số cho đến nay. catlà sức mạnh của 2 mà tôi sẽ cần nhân lên numđể ghép nối numtrước mặt sum(vì vậy tôi có thể chỉ cần thêm).


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

Vòng lặp: Kiểm tra xem f_ncó đúng hơn không pow.

Sự thật:

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

Không có rác. Sau đó, thêm num* catvào sum. Tiếp theo, tải số Fibonacci tiếp theo (= f_(n-1); nếu nó không tồn tại, thoát khỏi vòng lặp) và đặt catthành cat* pow. Chuẩn bị cho vòng lặp tiếp theo (không có thêm rác, thay đổi phạm vi một).

Falsey:

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

Đặt powthành 2 * pow, khôi phục num.

]

Lặp lại cho đến khi không còn số Fibonacci.


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

Làm sạch rác. Lấy từng chữ số của số kết quả và đầu ra mỗi (trong ascii).


7

Husk , 7 byte

ḋṁḋ↑Θİf

Hãy thử trực tuyến!

Giải trình

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

Chào mừng đến với PPCG! :)
DJMcMayhem

5

Japt , 9 byte

ÆMgX ¤Ã¬Í

Chạy nó

Giải trình:

Æ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! Đánh tôi đi!
Shaggy

1
@Shaggy Tôi biết người này sẽ là một cuộc đua với bạn: P
Oliver

4

Bình thường, 22 byte

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

Hãy thử nó ở đây

Giải trình

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 byte

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

Giải trình:

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

Thay đổi

  • -13 bằng cách sử dụng bsr. Cảm ơn Peter Cordes!
  • -2 bằng cách đăng ký zeroing vớimul .

  • -1 bằng cách sử dụng vòng lặp while thay vì looppush/ pop ecx(tín dụng Peter Cordes).

Nhập vào edi , đầu ra trong 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
Sử dụng leađể thay đổi và thêm vào trong fib2. Ngoài ra, trích xuất từng bit một tại một thời điểm là không cần thiết. Sử dụng bsr %eax, %ecxđể tìm số bit trong biểu diễn nhị phân và sử dụng dịch chuyển theo CL / hoặc để hợp nhất, giống như câu trả lời Python của Dennis đang làm.
Peter Cordes

1
Bạn cần clsố lượng ca làm việc, vì vậy hãy lấy bộ đếm vòng lặp của bạn theo một reg khác (như %edi) và sử dụng dec %edi / jnz(3 byte trong mã 32 bit, 4 byte trong 64 bit). Trong mã 32 bit, giúp tiết kiệm tổng cộng 1 byte từ việc giảm ecx đẩy / pop. Đừng rơi vào cái bẫy của việc sử dụng loopkhi nó làm cho vấn đề trở nên khó khăn hơn, không dễ dàng hơn. (Quy ước gọi điện của bạn đã được tùy chỉnh, ghi đè %ebx, vì vậy đừng gọi chức năng của bạn main) Bạn có thể quay lại EAX trong khi vẫn tận dụng lợi thế của 1 byte xchg, không cần phải không chuẩn nếu bạn không cần.
Peter Cordes

1
Bạn có thể thay thế thêm inc %ecxsố lượng ca bằng một ca làm thêm trái khi bạn thêm, sử dụng lea (%eax, %edx, 2), %edx. Trung tính tính bằng byte cho 32 bit, lưu một cho x86-64. Nhưng tiết kiệm một hướng dẫn.
Peter Cordes

1
Mỗi lần tôi sử dụng loopmã golf, tôi cảm thấy bẩn. Cũng không hoàn toàn, nhưng thất vọng vì tôi không thể tìm thấy một triển khai nhỏ như nhau mà tránh được chỉ dẫn chậm chạp đó; bên ngoài mã golf, looplà một trong những thú cưng của tôi . Tôi ước rằng nó nhanh trên các CPU hiện đại, bởi vì nó sẽ rất tốt cho các vòng lặp có độ chính xác mở rộng mà không có các cột cờ một phần, nhưng nó không và chỉ nên được coi là một hướng dẫn tối ưu hóa kích thước tối nghĩa làm cho mã của bạn chậm.
Peter Cordes

1
Dù sao, công việc tốt. Khác với đẩy / pop / loop -> dec / jnz, tôi không thấy bất kỳ khoản tiết kiệm nào, chỉ là tốc độ tăng tốc LEA trung tính ở kích thước mã. Tôi luôn tự hỏi liệu có bao giờ một trường hợp sử dụng thực sự cho xor/ multrick thành không ba thanh ghi không (bạn có bao giờ cần nhiều số không?), Nhưng sử dụng nó như là một phần của việc tạo ra 1nó hợp lý hơn.
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)

Phiên bản bị đánh cắp:

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
Chào mừng bạn đến với sân golf PPCG và Haskell nói riêng! Một cách ngắn hơn để tạo ra một danh sách vô số các số Fibonacci là f=0:scanl(+)1f(được lấy từ đây ). Các chức năng có thể ẩn danh, vì vậy bạn có thể bỏ vị trí hàng đầu g=, xem Hướng dẫn về Quy tắc Ggolfing của chúng tôi trong Haskell .
Laikoni

Cảm ơn! Điều đó bù cho một số chức năng dài hơn được sử dụng. Tôi đã dành một khoảng thời gian để cố gắng tìm ra cách để thực hiện dịch chuyển bit theo cách ngắn gọn hơn, nhưng đã xuất hiện ngắn.
dùng9549915

Bạn có thể thay thế $realToFrac ybằng .read.show$ymột byte
H.PWiz


1

APL + THẮNG, 55 byte

Nhắc nhở cho đầu vào màn hình của số nguyên.

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

Độ chính xác số nguyên tối đa của APL + WIN là 17 và giới hạn số nguyên là thứ tự 10E300 do đó số đầu vào tối đa là 55 và kết quả là: 1.2492739026634838E300



1

Thạch , 6 byte

ḶÆḞBFḄ

Hãy thử trực tuyến!

phạm vi owered -> n th ÆḞsố ibonacci -> từ tháng mười hai đến Binary -> Flatten -> từ inary vào tháng mười hai


Không hiểu ngôn ngữ này nhưng tôi nghĩ đầu ra không phải lúc nào cũng đúng. ví dụ: Input 10và bạn sẽ nhận được một 16024033463, nó không chính xác (câu trả lời đúng là 250375522).
Guoyang Tần

@AbrahamChin Trả về đầu vào10250375522
Dennis


1

MATL , 21 byte

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

Hãy thử trực tuyến!

Giải trình

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.

Hãy thử trực tuyến!

Giải trình

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

Hãy thử trực tuyến!

Vì vậy, tôi đã tìm kiếm một cách để xuất số lượng Wikipedia bằng cách sử dụng chuỗi, cho đến khi tôi tìm thấy điều này . Hóa ra bạn có thể tính toán chuỗi trò chơi thông qua làm tròn, vì vậy tôi đã thử thách với chức năng đệ quy.

Tôi thấy cách tiếp cận "làm tròn" thực sự thú vị, cũng là một giáo sư đã cho tôi thấy điều này cách đây một thời gian.

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

Giải trình

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

Ngoài ra kiểm tra bài viết stackoverflow này câu trả lời tốt nhất đề cập đến cùng một bài viết trên Wikipedia.


Cách thú vị để làm điều đó!
Nathan Wood

1

Stax , 9 byte

ü1∞╓♪εw≤+

Chạy và gỡ lỗi nó tại staxlang.xyz!

Giải nén (10 byte) và giải thích:

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

Bình thường, 27 byte

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

Bộ kiểm tra

Dịch thuật 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

Bộ kiểm tra

Dịch thuật 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)

Chương trình kiểm tra

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

Nó hỗ trợ lên đến 10, thay đổi .i(2)cho .toLong(2)sẽ hỗ trợ lên đến 14 nếu cần thiết


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

Hãy thử trực tuyến!

Đã lưu một số byte bằng cách ghép các vectơ số, không phải chuỗi. Trường hợp đặc biệt đẫm máu cho 0!


Chức năng được chấp nhận. Ngoài ra, sẽ hiệu quả hơn nhiều khi thay đổi kết quả còn lại bằng số bit sau đó làm phiền với các vectơ số. Xem câu trả lời con trăn của tôi hoặc Dennis. Điều này có thêm lợi ích của việc xử lý 0 trường hợp.
qwr

codegolf.stackexchange.com/questions/4024/tips-for-golfing-in-r R chơi golf quá nhiều đối với tôi: /
qwr

@qwr Câu trả lời không phải là hàm; Tôi đang tạo một hàm trợ giúp vì nó phải là sapplymột vectơ do thực tế là nó được đệ quy. Nó không thể được gói gọn trong một dòng. Như bạn thấy, chương trình sẽ nhắc nhập dữ liệu của người dùng và sau đó trả về câu trả lời. Một byte có thể được lưu bằng cách tạo một lối tắt cho ifelse. Và ... chúng ta có thể loại bỏ ,""khỏi scan, vâng.
Andreï Kostyrka
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.