Chuyển đổi một số từ Đại diện Zeckendorf sang Số thập phân


18

Giới thiệu về Zeckendorf Đại diện / Số Fibonacci cơ sở

Đây là một hệ thống số sử dụng các số Fibonacci làm cơ sở. Các số bao gồm 0 và 1 và mỗi 1 có nghĩa là số đó chứa số Fibonacci tương ứng và 0 có nghĩa là không.

Ví dụ: hãy chuyển đổi tất cả các số tự nhiên <= 10 thành Fibonacci cơ sở.

  • 1 sẽ trở thành 1, bởi vì nó là tổng của 1, là số Fibonacci,

  • 2 sẽ trở thành 10, vì đó là tổng của 2, là số Fibonacci và không cần 1, vì chúng tôi đã đạt được tổng mong muốn.

  • 3 sẽ trở thành 100, vì đó là tổng của 3, là số Fibonacci và nó không cần 2 hoặc 1 vì chúng tôi đã đạt được số tiền mong muốn.

  • 4 sẽ trở thành 101, vì nó là tổng của [3,1], cả hai đều là số Fibonacci.
  • 5 sẽ trở thành 1000, vì đó là tổng của 5, là số Fibonacci và chúng tôi không cần bất kỳ số nào khác.
  • 6 sẽ trở thành 1001, bởi vì nó là tổng của các số Fibonacci 5 và 1.
  • 7 sẽ trở thành 1010, bởi vì nó là tổng của các số Fibonacci 5 và 2.
  • 8 sẽ trở thành 10000, bởi vì nó là một số Fibonacci.
  • 9 sẽ trở thành 10001, bởi vì nó là tổng của các số Fibonacci 8 và 1.
  • 10 sẽ trở thành 10010, bởi vì nó là tổng của các số Fibonacci 8 và 2.

Chúng ta hãy chuyển đổi một số Fibonacci cơ sở ngẫu nhiên, 10101001010 thành số thập phân: Đầu tiên chúng ta viết các số Fibonacci tương ứng. Sau đó, chúng tôi tính tổng của các số dưới 1.

 1   0   1   0   1   0   0   1   0   1   0
 144 89  55  34  21  13  8   5   3   2   1  -> 144+55+21+5+2 = 227.

Đọc thêm về các số Fibonacci cơ sở: liên kết , nó cũng có một công cụ chuyển đổi các số nguyên thông thường thành các số liệu cơ sở. Bạn có thể thử nghiệm với nó.

Bây giờ câu hỏi:

Nhiệm vụ của bạn là lấy một số trong Biểu diễn Zeckendorf và xuất giá trị thập phân của nó.

Đầu vào là một chuỗi chỉ chứa 0 và 1 (mặc dù bạn có thể lấy đầu vào theo bất kỳ cách nào bạn muốn).

Xuất một số ở dạng thập phân.

Các trường hợp thử nghiệm: (ở định dạng đầu vào-> đầu ra)

 1001 -> 6
 100101000 -> 73
 1000000000 -> 89
 1001000000100100010 -> 8432
 1010000010001000100001010000 -> 723452

Đây là môn đánh gôn, vì vậy câu trả lời ngắn nhất bằng byte sẽ thắng.

Lưu ý: Đầu vào sẽ không chứa bất kỳ 0 hàng đầu hoặc 1 liên tiếp nào.


Chúng ta có thể lấy đầu vào như một danh sách các bit?
Thuật sĩ lúa mì

Giống như, lấy mã hóa đầu vào ascii sau đó chuyển đổi nó thành nhị phân hoặc một cái gì đó như thế?
Bánh quy cối xay gió

4
Chúng tôi có thể nhận đầu vào theo thứ tự LSB đầu tiên không?
Mego


1
@Mego Có, bạn có thể
Bánh quy cối xay gió

Câu trả lời:


19

Taxi , 1987 1927 byte

-60 byte do nhận ra rằng ngắt dòng là tùy chọn.

Go to Post Office:w 1 l 1 r 1 l.Pickup a passenger going to Chop Suey.Go to Chop Suey:n 1 r 1 l 4 r 1 l.[B]Switch to plan C if no one is waiting.Pickup a passenger going to Cyclone.Go to Cyclone:n 1 l 3 l.Pickup a passenger going to Narrow Path Park.Pickup a passenger going to Sunny Skies Park.Go to Zoom Zoom:n.Go to Sunny Skies Park:w 2 l.Go to Narrow Path Park:n 1 r 1 r 1 l 1 r.Go to Chop Suey:e 1 r 1 l 1 r.Switch to plan B.[C]1 is waiting at Starchild Numerology.1 is waiting at Starchild Numerology.Go to Starchild Numerology:n 1 l 3 l 3 l 2 r.Pickup a passenger going to Addition Alley.Pickup a passenger going to Cyclone.Go to Cyclone:w 1 r 4 l.[D]Pickup a passenger going to Addition Alley.Pickup a passenger going to Cyclone.Go to Addition Alley:n 2 r 1 r.Go to Cyclone:n 1 l 1 l.Pickup a passenger going to Multiplication Station.Go to Zoom Zoom:n.Go to Narrow Path Park:w 1 l 1 l 1 r.Switch to plan E if no one is waiting.Pickup a passenger going to The Babelfishery.Go to The Babelfishery:e 1 r.Pickup a passenger going to Multiplication Station.Go to Multiplication Station:n 1 r 2 l.Pickup a passenger going to Joyless Park.Go to Joyless Park:n 2 l 1 r 1 r.Go to Addition Alley:w 1 r 2 l 1 l.Pickup a passenger going to Cyclone.Go to Cyclone:n 1 l 1 l.Pickup a passenger going to Addition Alley.Switch to plan D.[E]Go to Addition Alley:w 1 l 1 r 1 l.Pickup a passenger going to Riverview Bridge.Go to Riverview Bridge:n 1 r.Go to Joyless Park:e 1 r 2 l.Pickup a passenger going to Addition Alley.[F]Switch to plan G if no one is waiting.Pickup a passenger going to Addition Alley.Go to Fueler Up:w 1 l.Go to Addition Alley:n 3 l 1 l.Pickup a passenger going to Addition Alley.Go to Joyless Park:n 1 r 1 r 2 l.Switch to plan F.[G]Go to Addition Alley:w 1 r 2 l 1 l.Pickup a passenger going to The Babelfishery.Go to The Babelfishery:n 1 r 1 r.Pickup a passenger going to Post Office.Go to Post Office:n 1 l 1 r.

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

Vì cuối cùng tôi không quay trở lại Taxi Garage, sếp của tôi đuổi việc tôi, nên nó thoát ra với một lỗi.


Joyless Parkcó vẻ là một nơi tốt đẹp để ghé thăm
aloisdg nói rằng Rebstate Monica

Chà, nó ít nhân vật hơn Sunny Skies Park.
JosiahRyanW

11

Perl 6 , 28 23 byte

{[+] (1,2,*+*...*)Z*$_}

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

Codeblock ẩn danh nhận danh sách 1s và 0s theo thứ tự LSB và trả về một số.

Giải trình:

{                     }   # Anonymous codeblock
 [+]                      # The sum of
     (1,2,*+*...*)        # The infinite Fibonacci sequence starting from 1,2
                  Z*      # Zip multiplied by
                    $_    # The input list in LSB form



4

Haskell , 38 byte

f=1:scanl(+)2f
sum.zipWith(*)f.reverse

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

Đưa đầu vào dưới dạng danh sách 1s và 0.

Giải trình


f=1:scanl(+)2f

Làm cho một danh sách các số Fibonacci thay đổi số đầu tiên f.

sum.zipWith(*)f.reverse

Lấy danh sách đầu vào reverselà bội số của mỗi mục nhập với mục nhập tương ứng f, sau đó sumlà kết quả.

Haskell , 30 byte

f=1:scanl(+)2f
sum.zipWith(*)f

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

Nếu trước tiên chúng ta lấy đầu vào với bit ít quan trọng nhất thì chúng ta không cần reverseđể có thể tiết kiệm 8 byte.


4

Python 2 , 43 byte

a=b=0
for x in input():b+=a+x;a=b-a
print b

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

Lấy đầu vào như một danh sách. Bản cập nhật là phiên bản ngắn hơn a,b=b+x,a+b+x, giống như bản cập nhật Fibonacci a,b=b,a+bnếu bạn bỏ qua x.


Python 2 , 45 byte

f=lambda n,a=1,b=1:n and n%10*b+f(n/10,b,a+b)

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

Lấy đầu vào dưới dạng số thập phân.


3

Bình thường, 13 byte

Hầu hết điều này (8 byte) chỉ là tạo ra các số Fibonacci.

s*V_m=+Z|~YZ1

Hãy thử nó với bộ thử nghiệm này!

Giải trình:

s*V_m=+Z|~YZ1QQ     Autofill variables
    m=+Z|~YZ1Q      Generate the first length(input) Fibonacci numbers as follows:
       Z             Start with Z=0
         ~YZ         And Y=[] (update it to Y=Z, return old Y)
        |   1        if Y is [], then replace with 1
      +              Sum Z and Y
     =               Replace Z with sum
    m                Repeat process
             Q       once for each element of the input
   _                Reverse the order of the Fibonacci numbers
 *V                 Vectorize multiplication
s                   Sum


3

J , 24 14 byte

#.~2+&%&1~#-#\

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

Đánh xuống phiên bản 24 byte sử dụng cơ sở hỗn hợp cho Fibonacci.

Làm thế nào nó hoạt động

#.~2+&%&1~#-#\  Example input: y=1 0 0 1 0
          #-#\  Length minus 1-based indices; 4 3 2 1 0
   2     ~      Starting from 2, run the following (4,3,2,1,0) times:
    +&%&1         Given y, compute 1 + 1 / y
                The result is 13/8 8/5 5/3 3/2 2
#.~             Mixed base conversion of y into base above; 2+8=10

J , 21 byte

1#.|.*[:+/@(!~#-])\#\

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

Phiên bản tinh chỉnh của giải pháp 25 byte của Galen Ivanov .

Sử dụng tổng đường chéo của tam giác Pascal, tương đương với tổng các hệ số nhị thức:

Fn= =ΣTôi= =0nn-TôiCTôi

Làm thế nào nó hoạt động

1#.|.*[:+/@(!~#-])\#\
                       Example input: 1 0 0 1 0
                   #\  Generate 1-based index; 1 2 3 4 5
      [:          \    For each prefix of above... (ex. 1 2 3)
              #-]        Subtract each element from the length (ex. 2 1 0)
           (!~   )       Compute binomial coefficient (ex. 3C0 + 2C1 + 1C2)
        +/@              Sum
                       The result is Fibonacci numbers; 1 2 3 5 8
   |.*                 Multiply with mirrored self; 0 2 0 0 8
1#.                    Sum; 10

J , 24 byte

3 :'y#.~|.(1+%)^:(<#y)2'

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

Động từ rõ ràng đơn âm. Tạo cơ sở hỗn hợp đại diện cho cơ sở Fibonacci, sau đó đưa vào chuyển đổi cơ sở #..

Làm thế nào nó hoạt động

y#.~|.(1+%)^:(<#y)2  Explicit verb, input: y = Fibonacci digit array, n = length of y
      (1+%)          x -> 1 + 1/x
           ^:(<#y)2  Apply the above 0..n-1 times to 2
                     The result looks like 2/1, 3/2, 5/3, 8/5, 13/8, ...
    |.               Reverse
                     Now, if it is fed into #. on the left, the digit values become
                     ...(8/5 * 5/3 * 3/2 * 2/1), (5/3 * 3/2 * 2/1), (3/2 * 2/1), 2/1, 1
                     which is ... 8 5 3 2 1 (Yes, it's Fibonacci.)
y#.~                 Convert y to a number using Fibonacci base

Lựa chọn thay thế

J , 27 byte

}.@(+#{.3#{.)^:(<:@#)@(,&0)

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

Ý tưởng:

 1  0  0  1  0  1
-1 +1 +1
------------------
    1  1  1  0  1
   -1 +1 +1
------------------
       2  2  0  1
      -2 +2 +2
------------------
          4  2  1
         -4 +4 +4
------------------
             6  5
            -6 +6 +6 <- Add an imaginary digit that has value 1
---------------------
               11  6
              -11+11
---------------------
                  17 <- the answer

J , 30 byte

0.5<.@+(%:5)%~(-:>:%:5)#.,&0 0

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

Điều này đã mất nhiều nỗ lực nhất để xây dựng. Sử dụng biểu thức dạng đóng với thủ thuật làm tròn. Trong biểu thức, giá trị 0 và 1 tương ứng là 0 và 1, do đó công suất chữ số thực phải bắt đầu bằng 2.

0.5<.@+(%:5)%~(-:>:%:5)#.,&0 0  Tacit verb.
                         ,&0 0  Add two zeroes at the end
              (-:>:%:5)#.       Convert to a number using base phi (golden ratio)
       (%:5)%~                  Divide by sqrt(5)
0.5<.@+                         Round to nearest integer

Mặc dù lỗi ( ((1-sqrt(5))/2)^nđiều khoản) có thể tích tụ, nhưng nó không bao giờ vượt quá 0,5, vì vậy thủ thuật làm tròn hoạt động đến vô cùng. Về mặt toán học:

tối đa(|error|)= =15Σ1(1-52)2n= =15Σ0(1-52)n= =5-125<12


Giải pháp tốt đẹp! Tôi rất vui khi thấy một động từ rõ ràng đánh bại giải pháp ngầm.
Galen Ivanov

Tôi đang cố gắng tìm một giải pháp ngầm ngắn hơn, nhưng không thành công. 25 byte cho bây giờ . Tôi sử dụng bộ ba của Pascal.
Galen Ivanov

@GalenIvanov Xem xét lại thử thách sau một năm, tôi đã nhận được một giải pháp ngầm mới, siêu ngắn :)
Bubbler

Thật tuyệt! Tôi sẽ xem xét chi tiết sớm hơn.
Galen Ivanov

2

MathGolf , 8 6 byte

{î)f*+

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

Giải trình

{        Start block (foreach in this case)
 î)      Push loop index (1-based) and increment by 1
   f     Get fibonacci number of that index
    *    Multiply with the array value (0 or 1)
     +   Add top two elements of stack. This implicitly pops the loop index the first iteration, which makes the addition become 0+a, where a is the top of the stack.

Đã lưu 1 byte nhờ JoKing và một byte khác nhờ đặt hàng LSB.


Lệnh LSB thực sự được cho phép. Ngoài ra, -1 byte
Jo King

@JoKing Tất nhiên, tôi thậm chí đã thực hiện bổ sung ngầm chỉ mới tuần trước ... Cảm giác tuyệt vời, bây giờ MathGolf đang ở vị trí đầu tiên!
maxb

2

05AB1E , 11 9 8 byte

vyiNÌÅfO

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

Giải trình:

v             : For each character in input string (implicit) in LSB order
  yi          : If the current character is truthy (1)
    NÌ        : Add 2 to the current index
       ÅfO    : Add the fibonacci of this number to the stack
  • -2 byte : Cảm ơn @KevinCruijssen đã chỉ ra những cách nhỏ để rút ngắn mã này!
  • -1 byte : Cảm ơn @Jonathan ALLan đã chỉ ra thứ tự LSB cho đầu vào!

1
Bạn có thể loại bỏ Θ. 1là sự thật trong 05AB1E rồi. :) Ngoài ra, 2+có thể được Ì.
Kevin Cruijssen

1
Chúng ta có thể lấy đầu vào ở dạng Little-endian (nghĩa là đảo ngược), nên lưu một byte (hoặc hai?).
Jonathan Allan




1

Stax , 6 byte

çéC◘0â

Chạy và gỡ lỗi nó

:1F^|5+           #Full program, unpacked, implicit input as array    
:1                #Get indicies of truthy
  F               #Use rest of program to loop through elements
   ^              #Increment current element
    |5+           #Get n-th fib and Add

Khá thẳng về phía trước. Đặt hàng LSB.



1

C (gcc) , 63 byte

Lấy đầu vào là một mảng của 10, cùng với chiều dài của mảng. Giải pháp này là một vòng lặp ngược khá thẳng về phía trước.

f(_,l,a,b,t)int*_;{a=b=1;for(t=0;l--;b=(a+=b)-b)t+=a*_[l];_=t;}

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


1

Prolog (SWI) , 74 byte

\D-->[X,Y],{D is 2*X+Y};[D];a,\D.
a,[A],[B]-->[X,Y,Z],{A is X+Y,B is X+Z}.

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

Lấy đầu vào dưới dạng danh sách các số nguyên 1 và 0 với bit có ý nghĩa nhất trước tiên.


0

Võng mạc 0.8.2 , 23 byte

0?
;
+`1;(1*);
;1$1;1
1

Hãy thử trực tuyến! Liên kết bao gồm các trường hợp thử nghiệm nhanh hơn. Giải trình:

0?
;

Chèn dải phân cách ở mọi nơi và xóa bất kỳ số không. Ví dụ, 1001trở thành ;1;;;1;.

+`1;(1*);
;1$1;1

Liên tục thay thế từng cái 1bằng một 1trong hai vị trí tiếp theo, vì tổng giá trị của chúng bằng giá trị của bản gốc 1. 1Do đó di chuyển và tích lũy cho đến khi chúng đạt đến hai vị trí cuối cùng, mà (do dải phân cách mới được thêm vào) bây giờ cả hai đều có giá trị 1.

1

Đếm 1s.




0

Trên thực tế , 8 byte

;r⌐@░♂FΣ

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

Đầu vào được lấy dưới dạng danh sách các bit theo thứ tự đầu tiên LSB.

Giải trình:

;r⌐@░♂FΣ
;r        range(0, len(input))
  ⌐       add 2 to every element in range (range(2, len(input)+2))
   @░     filter: take values in range that correspond to 1s in input
     ♂F   Fibonacci number at index of each element in list (Actually uses the F(0)=F(1)=1 definition, which is why we needed to add 2 earlier)
       Σ  sum

0

Powershell, 68 byte

param($s)$b=1
$s[$s.Length..0]|%{$a,$b=$b,($a+$b)
$x+=($_-48)*$b}
$x

Kịch bản thử nghiệm:

$f = {
param($s)$b=1
$s[$s.Length..0]|%{$a,$b=$b,($a+$b)
$x+=($_-48)*$b}
$x
}

@(
    ,("1001", 6)
    ,("100101000", 73)
    ,("1000000000", 89)
    ,("1001000000100100010", 8432)
    ,("1010000010001000100001010000", 723452)
) | % {
    $s,$e = $_
    $r = &$f $s
    "$($r-eq$e): $r"
}

Đầu ra:

True: 6
True: 73
True: 89
True: 8432
True: 723452

0

Java (OpenJDK 8) , 65 byte

Khá nhỏ cho một câu trả lời Java cho tôi hài lòng với điều đó. Đưa đầu vào dưới dạng mảng ints được đặt hàng đầu tiên của LSB.

d->{int s=0,f=1,h=1;for(int i:d){s+=i>0?f:0;f=h+(h=f);}return s;}

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

Ung dung

d->{                        // Lambda function that takes array of ints
    int s=0,f=1,h=1;        // Initialise sum and fibonacci vars
    for(int i:d){           // Loop through each input integer
        s+=i>0?f:0;         // If it's 1 add current fibonacci number to sum
        f=h+(h=f);          // Increase fibonacci number 
    }return s;              // return sum
}

0

Z80Golf , 34 byte

00000000: dde1 f1b7 2819 fe30 2812 4504 aff5 3cf5  ....(..0(.E...<.
00000010: d1f1 82d5 f510 f9c1 f17c 8067 2c18 e3dd  .........|.g,...
00000020: e5c9                                     ..

Ví dụ với đầu vào 1001-Hãy thử trực tuyến!

Ví dụ với đầu vào 100101000-Hãy thử trực tuyến!

Hội,, tổ hợp:

zeck:		; input=push on stack in MSB order (eg top is LSB) output=reg h
pop ix		; save return addr in ix
f:
pop af		; get next digit
or a
jr z, return	; if current digit==0, return
cp 0x30
jr z, skip	; if current digit=='0' (e.g. not '1'), skip loop
ld b, l		; find fib of counter
fib:
	inc b	; 1-indexing for func to work
	xor a	; set a to 0 (1st fibo num)
	push af
	inc a	; set a to 1 (2nd fibo num)
	push af
	fib_loop:
		pop de
		pop af
		add d
		push de
		push af
		djnz fib_loop
pop bc		; get the fibo num just calculated
pop af		; pop just to reset stack frame
ld a, h
add b		; add current fibo number to sum
ld h, a
skip:
inc l		; increment counter reg
jr f		; repeat loop
return:
push ix		; push the return addr to ret to it
ret
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.