Có phải con số này là bí mật Fibonacci?


23

Lý lịch

Hầu hết các bạn đều biết số Fibonacci là gì. Một số bạn có thể biết rằng tất cả các số nguyên dương có thể được biểu diễn dưới dạng tổng của một hoặc nhiều số Fibonacci khác biệt, theo Định lý của Zeckendorf . Nếu số lượng thuật ngữ trong Zeckendorf tối ưu Biểu diễn của một số nguyên ntự nó là một số Fibonacci, chúng ta sẽ gọi là n"bí mật" Fibonacci.

Ví dụ:

139 = 89 + 34 + 13 + 3
This is a total of 4 integers. Since 4 is not a Fibonacci number, 139 is not secretly Fibonacci

140 = 89 + 34 + 13 + 3 + 1
This is a total of 5 integers. Since 5 is a Fibonacci number, 140 is secretly Fibonacci

Ghi chú

  • Có thể tìm thấy Đại diện Zeckendorf tối ưu bằng thuật toán tham lam. Chỉ cần lấy số Fibonacci lớn nhất <= n và trừ nó từ n cho đến khi bạn đạt 0
  • Tất cả các số Fibonacci có thể được biểu diễn dưới dạng tổng của 1 số Fibonacci (chính nó). Vì 1 là số Fibonacci, nên tất cả các số Fibonacci cũng bí mật là Fibonacci.

Thử thách

Thử thách của bạn là viết một chương trình hoặc hàm lấy một số nguyên và trả về việc số nguyên đó có phải là Fibonacci bí mật hay không.

Đầu vào

Bạn có thể lấy đầu vào ở bất kỳ định dạng hợp lý. Bạn có thể giả sử đầu vào sẽ là một số nguyên dương duy nhất.

Đầu ra

Xuất ra một trong hai kết quả khác nhau cho dù đầu vào có bí mật là Fibonacci hay không. Ví dụ bao gồm True/ False, 1/ 0, v.v.

Chấm điểm

Đây là , vì vậy câu trả lời ngắn nhất bằng byte thắng! Sơ hở tiêu chuẩn bị cấm.

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

Truthy (secretly Fibonacci)
1
2
4
50
140
300099

Falsey (NOT secretly Fibonacci)
33
53
54
139
118808

6
Điều này có nghĩa là họ tò mò?
kevin

2
Trong trường hợp nó được sử dụng cho bất kỳ ai: Tổng tối ưu là giải pháp duy nhất không sử dụng hai số Fibonacci liên tiếp.
kasperd

2
@kasperd Bạn đã đúng, điều này có ý nghĩa nếu bạn nghĩ về nó. Nếu giải pháp có hai số Fibonacci liên tiếp, chúng có thể được thêm vào với nhau để tạo thành số tiếp theo. Nếu giải pháp của bạn chứa 5 và 8, nó sẽ kém tối ưu hơn so với chỉ có một 13.
Cowabunghole

@Cowabunghole Đó là trực giác. Một bằng chứng đầy đủ là một chút phức tạp hơn thế. Nếu giải pháp đã chứa 5, 8 và 13, bạn sẽ thêm 8 + 13 chứ không phải 5 + 8. Và hướng khác cần phải được chứng minh là tốt.
kasperd

Câu trả lời:



8

Python 2 , 77 byte

def f(n):z=[bin(x).count('1')for x in range(n*n+1)if x&2*x<1];print z[z[n]]<2

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

Điều này sử dụng định lý rằng hai mô tả của OEIS A003714 là tương đương:

n=F(i1)+F(i2)++F(ik)nna(n)=2i1+2i2++2ik 11

Chúng tôi tạo ra đủ * số như vậy, và sau đó sử dụng znhư một ánh xạ từ các số nguyên không âm sang Số lượng có bao nhiêu số hạng trong biểu diễn Zeckendorf của ? Khác bằng cách đếm 1s trong nhị phân.n

Sau đó, nó vẫn còn để kiểm tra nếu z[n]là một số Fibonacci, tức là z[z[n]] == 1.

* Ít nhất, cảm thấy như thế là đủ, và về mặt thực nghiệm thì dường như là đủ. Tôi sẽ chứng minh điều này một thời gian sau.n2+1


Bạn có thể cắt hai byte bằng cách loại bỏ các backticks xung quanh bin(x). Bạn cũng có thể loại bỏ một bằng cách thay đổi range(n*n+1)thành range(n<<n). (Giả sử 0 không hợp lệ)
nedla2004

Tôi không biết tôi đang nghĩ gì với những backticks xung quanh bin(x), haha. Và, hm, 1<<nđã là cách, cách quá đủ, nhưng tôi muốn giữ thời gian chạy phi thiên văn
Lynn

Điểm công bằng, tôi đoán việc có thể chạy mã có thể là một thuộc tính quan trọng. :)
nedla2004

6

Thạch , 15 byte

‘ÆḞ€fRṪạµƬL’Ɗ⁺Ị

Một liên kết đơn âm chấp nhận một số nguyên không âm sẽ sinh ra 1nếu "Bí mật Fibre" và mặt 0khác.

Hãy thử trực tuyến! (quá kém hiệu quả đối với các trường hợp thử nghiệm lớn hơn)

Làm sao?

‘ÆḞ€fRṪạµƬL’Ɗ⁺Ị - Link: integer, I
        µƬ      - perform the monadic link to the left as a function of the current I,
                - collecting up all the inputs until the results are no longer unique:
‘               -   increment I -> I+1
 ÆḞ€            -   nth Fibonacci number for €ach n in [1,I+1]
     R          -   range from 1 to I
    f           -   filter discard (discard Fibonacci numbers not in the range, i.e. > I)
      Ṫ         -   tail (get the largest)
       ạ        -   absolute difference with I
                - This gives us a list from I decreasing by Fibonacci numbers to 0
                - e.g. for 88 we get [88,33,12,4,1,0]
                -      because (88-33)+(33-12)+(12-4)+(4-1)+(1-0)=55+21+8+3+1=88 
          L     - length (the number of Fibonacci numbers required plus one)
           ’    - decrement (the number of Fibonacci numbers required)
            Ɗ   - treat the last three links (which is everything to the left) as a monad:
             ⁺  - ...and repeat it
                - i.e. get the number of Fibonacci numbers required for the number of
                -      Fibonacci numbers required to represent I.
                -      This is 1 if I is Secretly Fibonacci, and greater if not)
              Ị - insignificant? (is the absolute value of that <= 1?)


5

C # (.NET Core) , 124 115 98 byte

a=>{int n=0,b,c;for(;a>0;a-=b,n++)for(b=c=1;c<=a;b=c-b)c+=b;for(b=c=1;c<n;c+=b)b=c-b;return c==n;}

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

-3 byte: đã thay đổi vòng lặp while thành for (nhờ Olivier Grégoire )
-6 byte: chuyển trả về sử dụng biến, khởi tạo b và c bên ngoài các vòng lặp (nhờ Kevin Cruijssen )
-17 byte: điều kiện thay đổi trong vòng lặp thứ hai để di chuyển nếu ra khỏi vòng lặp và kết hợp với trả về, sử dụng lại các biến b và c trong vòng lặp cuối (nhờ raznagul )

Ung dung:

a => {
    int n = 0, b, c;                        // initialize variables

    for(; a > 0; a -= b, n++)               // increase n until a is 0
        for(b = c = 1; c <= a; b = c - b)   // set b and c to 1 for each a; set second largest Fibonacci number until largest Fibonacci number reaches a
            c += b;                         // set largest Fibonacci number of current sequence

    for(b = c = 1; c < n; c += b)           // while e is less than or equal to n, continue incrementing largest (e) Fibonacci number in the sequence
        b = c - b;                          // increment second-largest (d) Fibonacci number

    return c == n;                          // if c equals n, a is a secret Fibonacci number
}

1
for(;c<=a;b=c-b)c+=b;sẽ giúp bạn tiết kiệm 3 byte.
Olivier Grégoire

1
115 byte . Tôi đã loại bỏ tất cả {}các vòng lặp của các vòng lặp của bạn và đặt mọi thứ vào trong for-loops. Ngoài ra, tôi đã thêm một biến rmà chúng tôi đặt vào cuối cùng 1của bạn if(e==n)và trả về, vì vậy bạn chỉ có một biến return.
Kevin Cruijssen

Gọi tốt cho cả hai. Tôi đã cố gắng thay đổi vòng lặp while thành một for và bằng cách nào đó đã bỏ lỡ cách dễ dàng để làm điều đó. Có một biến riêng để trả lại chắc chắn là tốt hơn.
Meerkat

1
Bằng cách thay đổi điều kiện trong vòng lặp thứ hai để e<nbạn có thể di chuyển ifđến sau khi vòng lặp và consequentlly kết hợp nó với returncho 101 byte .
raznagul

1
Bạn có thể lưu thêm 3 byte bằng cách sử dụng lại bctrong vòng lặp cuối cùng và loại bỏ de.
raznagul

4

Perl 6 , 58 byte

{(1,&[+]...*>$_)∋($_,{$^n-(1,&[+]...^*>$n).tail}...0)-1}

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

1, &[+] ... * > $_ chỉ là chuỗi Fibonacci, dừng lại ở một nơi không vô hạn thuận tiện (số đầu vào).

$_, { $^n - (1, &[+] ...^ * > $n).tail } ... 0là một chuỗi các số, bắt đầu bằng số đầu vào và mỗi phần tử liên tiếp thu được bằng cách trừ đi số Fibonacci lớn nhất nhỏ hơn hoặc bằng phần tử trước đó từ phần tử trước. Trình tự kết thúc khi 0đạt được. Ví dụ, nếu $_140, thì chuỗi này là 140, 51, 17, 4, 1, 0.

Trừ một từ chuỗi này coi nó là một số, độ dài của nó và sự khác biệt là số lượng các số Fibonacci, được cộng lại với nhau, đưa ra số đầu vào. Sau đó, con số này được kiểm tra để trở thành thành viên trong chuỗi Fibonacci đầu tiên.


Tôi chưa từng thấy mánh khóe đó với &[+]trước đây! Tiết kiệm tuyệt vời khi không phải xác định hai thuật ngữ ban đầu
Jo King

1
51 byte bằng cách gán chuỗi Fibonacci cho một hàm và một vài thay đổi khác
Jo King

Câu trả lời JavaScript của cổng l4m2, 50 byte
nwellnhof

@nwellnhof Ha, tôi đã có khá nhiều điều tương tự, ngoại trừ một sự khác biệt nhỏ
Jo King

3

Perl 6 , 48 byte

{4>($_,{$_,{$_-(1,&[+]...*>$_)[*-2]}...^0}...1)}

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

Chuyển đổi đầu vào thành một danh sách Đại diện Zeckendorf liên tục cho đến khi đạt đến một số duy nhất và sau đó kiểm tra xem độ dài của chuỗi có nhỏ hơn 4 hay không.

Hàm Zenckendorf ở giữa hầu hết là từ câu trả lời của Sean với một vài cải tiến.

Giải trình:

{4>($_,{$_,{$_-(1,&[+]...*>$_)[*-2]}...^0}...1)}
{                                              } # Anonymous code block
                                          ...     # Define a sequence:
    $_  # That starts at the input
      ,{                                 }  # Each element is defined by:
                                   ... # Another sequence that:
        $_,   # Starts at the previous element
            $_-   # The previous element minus
                1,&[+]...*     # The Fibonacci sequence
                          >$_  # Ending when it is larger than the previous element
               (             )[*-2]  # The second from last element
          {                        }...^0  # Run until 0, discarding the last element
         # This returns the length of the Zeckendorf Representation
                                         ...1  # Run this until it is length 1
 4>(                                         )  # Return true if the length of the sequence is smaller than 4

Ví dụ, chuỗi cho 22 12đã là một số Fibonacci. Chuỗi cho 140140 5 1và vì 5 là một số Fibonacci nên điều này trả về đúng. Chuỗi cho 3333 4 2 1và vì 4không phải là số Fibonacci nên chuỗi có độ dài 4.


3

05AB1E , 14 byte

ΔDÅFθ-¼}¾ÅF¾<å

Hãy thử trực tuyến . Không có bộ kiểm tra nào cho tất cả các trường hợp kiểm tra, vì counter_variablekhông thể đặt lại về 0 .. Tôi đã xác minh tất cả bằng tay và chúng đều đúng.

Giải trình:

Δ      }          # Loop until the top of the stack no longer changes
 D                #  Duplicate the top of the stack
                  #  (implicitly the input in the first iteration)
  ÅF              #  Get a list of all Fibonacci numbers lower than this number
    θ             #  Get the last item (largest one)
     -            #  Subtract it from the number
      ¼           #  Increase the counter_variable by 1 every iteration
        ¾         # After the loop, push the counter_variable
         ÅF       # Get all Fibonacci numbers below this counter_variable
           ¾<     # Push the counter_variable again, and subtract 1
             å    # Check if this value is in the list of Fibonacci numbers
                  # (and output implicitly)

LƯU Ý: counter_variableSẽ là 5cho đầu vào 1396đầu vào 140, bởi vì để Δ-loop kiểm tra ngăn xếp vẫn giữ nguyên, tất nhiên nó không phải là một lần lặp bổ sung.



2

Võng mạc 0.8.2 , 61 byte

.+
$*
M`((?>\2?)(\1|\G.))*..|.
.+
$*
^(((?>\3?)(\2|^.))*.)?.$

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

.+
$*

Chuyển đổi sang unary.

M`((?>\2?)(\1|\G.))*..|.

Đếm số lượng số Fibonacci cần thiết.

Sự thay thế đầu tiên liên quan đến các số Fibonacci ít nhất là 2. Trên đường chuyền đầu tiên, \2chưa tồn tại, nhưng may mắn thay, đó là tùy chọn, vì vậy chúng tôi không phải khớp với nó. \1cũng không tồn tại, nhưng may mắn thay, chúng ta có sự thay thế \G.phù hợp với một nhân vật duy nhất khi bắt đầu trận đấu. Cả hai \2\1do đó đảm nhận giá trị 1.

Ở những lần tiếp theo, \2tồn tại, vì vậy chúng tôi cố gắng để phù hợp với nó. Lần này nếu nó thất bại thì \1cũng thất bại (vì nó lớn hơn \2), nhưng nếu nó thành công, thì việc (?>)ngăn chặn quay lại, vì vậy nếu \2khớp nhưng \1chúng ta không thử \1. ( \G1luôn luôn thất bại vì chúng tôi đã vượt qua giai đoạn bắt đầu của bản vá.) Cuối cùng \2sẽ nhận giá trị trước đó \1trong khi \1lấy tổng của hai giá trị.

Do đó, chúng tôi khớp nhiều số Fibonacci nhất có thể, thêm vào khi chúng tôi đi. Vì các tổng một phần của chuỗi 1, 2, 3, 5...0, 1, 3, 6, 11...nghĩa là ít hơn 2 so với các số Fibonacci, chúng tôi kết thúc bằng cách khớp 2 ở cuối.

Điều này rõ ràng là không khớp với chính nó nên một sự thay thế xử lý trường hợp đó.

.+
$*

Chuyển đổi sang unary.

^(((?>\3?)(\2|^.))*.)?.$

Kiểm tra xem đây có phải là số Fibonacci không. Điều này sử dụng ý tưởng tương tự như thử nghiệm đầu tiên nhưng nó sử dụng ^thay vì \Gvà chúng tôi cũng cần phải khớp chính xác, vì vậy nó sử dụng một tùy chọn chụp thay vì xen kẽ như golfer (nhưng nó tăng số lần chụp lên 1).

Võng mạc , 35 byte

.+
*
2}C`((?>\2?)(\1|\G.))*..|.
^1$

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

.+
*

Chuyển đổi sang unary.

C`((?>\2?)(\1|\G.))*..|.

Đếm số lượng số Fibonacci cần thiết. (Vòng lặp cả chuyển đổi và số đếm sẽ tiết kiệm được toàn bộ byte so với việc đếm số lượng đơn vị ở vị trí đầu tiên.)

2}

Thực hiện các bước trước hai lần trong tổng số. Điều này lấy số lượng các số Fibonacci cần thiết để tổng hợp với số lượng các số Fibonacci.

^1$

Nếu con số được bí mật là Fibonacci thì kết quả là 1.


1

Python 2 , 146 137 byte

lambda a:len(g(len(g(a))))<2
f=lambda n:n<3or f(n-2)+f(n-1)
def g(a,n=1):j=f(n-1);return[j]if a-j<1else[j]+g(a-j)if a-f(n)<0else g(a,n+1)

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

f () là một hàm đệ quy trả về giá trị của số Fibonacci thứ n. Lấy từ câu trả lời này .

g () là một hàm đệ quy trả về Biểu diễn Zeckendorf của số đã cho dưới dạng danh sách các số nguyên.

Vì tất cả các số Fibonacci sẽ có độ dài trả về của một mục từ g (), h () kiểm tra xem độ dài của g () của g (n) == 1.

EDIT: Đã lưu 9 byte nhờ nedla2004 . Tôi tiếp tục quên rằng lambdas không phải luôn là giải pháp tốt nhất ...


1
138 byte . Tôi chủ yếu chỉ thực hiện gmột chức năng để tôi có thể định nghĩa f(n-1)cho một biến. Thay đổi khác vài từ ==để <nơi họ đều giống nhau.
nedla2004
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.