Sản phẩm Fibonacci


13

Bạn có thể phân tách một số lớn hơn 0 dưới dạng một tổng duy nhất của các số Fibonacci dương. Trong câu hỏi này, chúng tôi thực hiện điều này bằng cách trừ đi nhiều lần số Fibonacci dương lớn nhất có thể . Ví dụ:

1 = 1
2 = 2
3 = 3
4 = 3 + 1
12 = 8 + 3 + 1
13 = 13
100 = 89 + 8 + 3

Bây giờ, tôi gọi một sản phẩm Fibonacci giống như các danh sách như trên, nhưng với phần bổ sung được thay thế bằng phép nhân. Ví dụ , f(100) = 89 * 8 * 3 = 2136.

Viết chương trình hoặc hàm đã cho số nguyên dương n trả về sản phẩm Fibonacci của số đó.


Testcase:

1: 1
2: 2
3: 3
4: 3
5: 5
6: 5
7: 10
8: 8
9: 8
42: 272
1000: 12831
12345: 138481852236

6
Tuyên bố không hoàn toàn chính xác. Ví dụ 2có thể được phân tách là -1 + 3. Phát biểu chính xác của định lý của Zeckendorf là ​​số Fibonacci dương có thể được phân tách duy nhất dưới dạng tổng của các số Fibonacci không liên tiếp có chỉ số dương.
Peter Taylor

1
@PeterTaylor Tôi không xem xét các số Fibonacci âm là một phần của chuỗi cho câu hỏi này. Liên tục hoặc không chỉ quan trọng khi bạn muốn các chỉ số, chúng tôi không quan tâm đến các chỉ số cho câu hỏi này.
orlp

1
Tôi không nói rằng bạn nên thay đổi câu hỏi để hỗ trợ các số Fibonacci âm: Tôi đang nói rằng bạn nên chỉnh sửa nó để rõ ràng về các giả định mà bạn đang thực hiện.
Peter Taylor

1
@orlp liên tiếp hay không quan trọng một chút, vì hai hình thức khác nhau sẽ cho hai sản phẩm khác nhau. Tuy nhiên, bạn đã nêu vấn đề theo cách hoàn toàn loại trừ các thuật ngữ Fibonacci liên tiếp, do đó, không có gì phải lo lắng về vấn đề đó.
hobbs

2
(cụ thể: F (n) và F (n + 1) đều không thể xuất hiện ở đầu ra vì thuật toán đảm bảo rằng, trước khi xem xét chúng, phần còn lại đã nhỏ hơn F (n + 2) = F (n) + F (n + 1))
hobbs

Câu trả lời:


5

Thạch , 16 15 byte

Rf1+С¤ṪạµÐĿIAP

Không đặc biệt nhanh hoặc thân thiện với bộ nhớ, nhưng đủ hiệu quả cho tất cả các trường hợp thử nghiệm. Hãy thử trực tuyến!

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

Rf1+С¤ṪạµÐĿIAP  Main link. Argument: n (integer)

         µ       Combine the chain to the left into a link.
          ÐĿ     Apply that link until the results are no longer unique.
                 Return the list of unique results.
      ¤            Combine the two links to the left into a niladic chain.
  1                  Set the left (and right) argument to 1.
   +D¡               Apply + to the left and right argument, updating the left
                     argument with the sum, and the right argument with the
                     previous value of the left one. Return the list of results.
                     Repeat this process n times.
                   This yields n + 1 Fibonacci numbers, starting with 1, 2.
R                  Range; map k to [1, ..., k].
 f                 Filter; keep the items in the range that are Fibonacci numbers.
       Ṫ           Tail; yield the last one or 0 if the list is empty.
        ạ          Absolute difference with k.
                   This is the argument of the next iteration.
            I    Compute the increments of the arguments to the loop, yielding
                 the selected Fibonacci numbers (with changed sign).
             A   Apply absolute value to each.
              P  Compute their product.  

6
Điều này có vẻ lớn, Dennis.
orlp

9

Python, 54 byte

f=lambda n,a=1,b=1:n<1or b>n and a*f(n-a)or f(n,b,a+b)

Chỉ cần một số đệ quy cũ tốt.


5

Perl, 69 63 + 4 ( -pl61cờ) = 67 byte

#!perl -pl61
while($_){$n=$m=1;($n,$m)=($m,$n+$m)until$m>$_;$_-=$n;$\*=$n}}{

Sử dụng:

> echo 42 | perl -pl61e 'while($_){$n=$m=1;($n,$m)=($m,$n+$m)until$m>$_;$_-=$n;$\*=$n}}{'

Ung dung:

while (<>) {
# code above added by -p
    # $_ has input value
    # $\ = 1 by -l61
    while ($_ != 0) {
        my $n = 1;
        my $m = 1;
        while ($m <= $_) {
            ($n, $m) = ($m, $n + $m);
        }
        $_ -= $n;
        $\ *= $n;
    }
} {
# code below added by -p
    print;  # prints $_ (undef here) and $\
}

Ideone .


Giải thích nên đề cập rằng bát phân 061là mã hóa ASCII cho ký tự '1'. Đẹp hack để sử dụng $\để có được in miễn phí.
Peter Cordes

2

JavaScript (ES6), 78 42 byte

f=(n,a=1,b=1)=>n?b>n?a*f(n-a):f(n,b,a+b):1

Câu trả lời của cảng @ Sp3000. Phiên bản 78 byte gốc:

f=(n,a=[2,1])=>n>a[0]?f(n,[a[0]+a[1],...a]):a.map(e=>e>n?0:(r*=e,n-=e),r=1)&&r

2

> <> , 57 byte

111\ ;n{/
:@+>:{:})?\$:@@
~{*}:0=?\}>:0${:})?$~:{$-$:1@?$

Dự kiến ​​số đầu vào sẽ có mặt trên ngăn xếp khi bắt đầu chương trình.

Xây dựng chuỗi Fibonacci (f0, f1, f2, ..., fn ) trên ngăn xếp cho đến khi đạt được một số lớn hơn đầu vào ( i). Sau đó, với một sản phẩm ( p) được khởi tạo thành 1...

while (i != 0)
   if (fn <= i)
      i = i - fn
      p = p * fn
   else
      i = i - 0
      p = p * 1
   discard fn
output p

Dùng thử trực tuyến!


Đẹp! Tôi đề nghị bạn đăng một liên kết bằng trình biên dịch trực tuyến
Luis Mendo


1

Bình thường, 24 byte

W=-QeaYh.WgQeH,eZsZ1;*FY

Dùng thử trực tuyến: Trình diễn hoặc Test Suite

Giải trình:

Q được gán với số đầu vào.

Phần h.WgQeH,eZsZ1tính toán số Fibonacci lớn nhất, nhỏ hơn hoặc bằngQ

h.WgQeH,eZsZ1
            1   start with H=Z=1
 .WgQeH         while Q >= end(H):
       ,eZsZ       H=Z=(end(Z), sum(Z))
h               first

Vì vậy, nếu Q = 10, nó tạo ra các số / cặp:

1 -> (1,1) -> (1,2) -> (2,3) -> (3,5) -> (5,8) -> (8,13) -> 8

Phần còn lại của mã tính toán phân vùng và nhân các số với nhau:

W=-QeaY...;*FY    implicit: Y = empty list
     aY...        add the calculated Fibonacci number to the empty list
    e             take the last element of Y (yes the number we just added)
 =-Q              and update Q with the difference of Q and ^
W         ;       continue until Q == 0
           *FY    multiply all number in Y and print

Rõ ràng có rất nhiều giải pháp ngắn hơn (với thời gian thực sự tồi tệ), như thế *FhfqQsTyeM.u,eNsNQ1.


1

Haskell, 44 byte

Yay cho đệ quy lẫn nhau:

(a&b)c|c<1=1|b>c=a*f(c-a)|d<-a+b=b&d$c
f=0&1
  • a là số Fibonacci trước đó
  • b là số Fibonacci hiện tại
  • c là đầu vào
  • f là chức năng mong muốn

Ít chơi gôn hơn:

(a & b) c | c == 0    = 1
          | c <  b    = a * f (c-a)
          | otherwise = b & (a + b) $ c
f x = (0 & 1) x

1

Trên thực tế, 22 byte

W;╗uR♂F;`╜≥`M░M;╜-WXkπ

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

Giải trình:

W;╗uR♂F;`╜≥`M░M;╜-WXkπ
                        (implicit input)
W                 W     while top of stack is truthy:
 ;╗                       push a copy of n to reg0
   uR♂F;                  push 2 copies of [Fib(a) for a in range(1, n+2)]
        `╜≥`M░            filter: take values where n <= Fib(a)
              M;          two copies of maximum (call it m)
                ╜-        subtract from n (this leaves n-m on top of the stack to be the new n next iteration, with a copy of m below it)
                   X    discard the 0 left over after the loop ends
                    kπ  product of all stack values

Có thực sự có mã hóa riêng của nó? Tôi đếm 35 byte trên 22 ký tự. Mothereff.in/ từ
mèo

1
@cat Cũng giống như Nghiêm túc, nó sử dụng CP437.
Mego

1

Javascript (ES6) 134 106 92 byte

Cảm ơn @cat vì đã phát hiện ra một không gian.

n=>{for(c=[a=b=s=1,1];a+b<=n;)a+=b,c.unshift(b+=a,a);c.map(i=>i<=n&&(n-=i)&(s*=i));alert(s)}

Chỉ là một phiên bản không được tối ưu hóa được thực hiện trên điện thoại của tôi, tôi đánh golf xuống, khi tôi về nhà. Ý tưởng được chào đón.


một khoảng trắng siêu nhỏ. : P
mèo

1

TRẢ LẠI , 44 byte

[a:[a;][1$[¤¤+$a;->~][]#%$␌a;\-a:]#␁[¤][×]#]

Try it here.

Lambda ẩn danh không hiệu quả đáng kinh ngạc mà kết quả trên Stack2. Sử dụng:

12345[a:[a;][1$[¤¤+$a;->~][]#%$␌a;\-a:]#␁[¤][×]#]!

LƯU Ý: và là các trình giữ chỗ cho các ký tự không thể in tương ứng của chúng: Biểu mẫu nguồn cấp dữ liệuBắt đầu tiêu đề .

Giải trình

[                                           ]  lambda
 a:                                            store input to a
   [  ][                         ]#            while loop
    a;                                           check if a is truthy
        1$[¤¤+$a;->~][]#%                        if so, generate all fibonacci numbers less than a 
                         $␌                      push copy of TOS to stack2
                           a;\-a:                a-=TOS
                                   ␁[¤][×]#   get product of stack2

Tôi đếm 46 byte trên 42 ký tự. Nếu RETURN sử dụng một số loại mã hóa đặc biệt, thì nó phải là 42 byte trên 42 ký tự, nhưng nó có vẻ là unicode, vì vậy nó là 46.
mèo

Trên thực tế, tôi chỉ nhận ra rằng tôi đã quên đưa vào một số không thể in được.
Mama Fun Roll

Tôi cần một chiếc kính hiển vi để nói chúng là gì, vì vậy tôi đã liên kết với chúng cho bạn. : D (Tôi không thể biết đó là SOH hay BOM)
con mèo

0

PHP, 119 byte

Mã (được bọc trên hai dòng để dễ đọc):

for($o=$c=1;$c<=$n=$argv[1];$f[++$k]=$c,$a=$b,$b=$c,$c+=$a);
for($i=$k;$i;$i--)for(;$n>=$d=$f[$i];$n-=$d,$o*=$d);echo$o;

Dòng đầu tiên tính toán trong $fcác số Fibonacci nhỏ hơn $n(đối số được cung cấp trong dòng lệnh). Dòng thứ hai tính toán các yếu tố Fibonacci (bằng phép trừ) và nhân chúng để tính toán sản phẩm trong$o .

Chuẩn bị mã với <?php(về mặt kỹ thuật không phải là một phần của chương trình), đặt mã vào một tệp ( fibonacci-factors.php) sau đó chạy dưới dạng:

$ php -d error_reporting=0 fibonacci-factors.php 100
# The output:
2136

Hoặc chạy nó bằng cách sử dụng php -d error_reporting=0 -r '... code here ...' 100 .

Mã không mã hóa và bộ thử nghiệm có thể được tìm thấy trên Github .


0

Q, 47 byte

m:{*/1_-':|(0<){y-x x bin y}[*+60(|+\)\1 0]\x}

Kiểm tra

+(i;m'i:1 2 3 4 5 6 7 8 9 42 1000 12345)

đọc nó dưới dạng cặp (i, map (m, i)), trong đó m là hàm tính toán và i là các đối số khác nhau

viết

1     1
2     2
3     3
4     3
5     5
6     5
7     10
8     8
9     8
42    272
1000  12831
12345 138481852236

Giải trình

n funtion\arg áp dụng hàm (hàm (hàm (... hàm (args))) n lần (bên trong sử dụng đệ quy Tal) và trả về chuỗi kết quả. Chúng tôi tính 60 mục đầu tiên của chuỗi fibonnaci là *+60(|+\)\1 0. Trong trường hợp đó, hàm là ( | +): + \ được áp dụng trên một chuỗi tính toán một phần tổng (ex + \ 1 2 3 là 1 3 6) và | đảo ngược seq. Vì vậy, mỗi 'lần lặp' chúng tôi tính tổng một phần của hai số trước đó các khoản tiền được đảo ngược. 60(|+\)\1 0tạo ra các chuỗi 1 0, 1 1, 2 1, 3 2, 5 3, 8 5, 13 8, 21 13, ...*+ áp dụng cho kết quả này lật (traspose) nó và lấy đầu tiên. Kết quả là chuỗi 1 1 2 3 5 8 13 21 34 55 ..

(cond)function\args áp dụng hàm (hàm (.. hàm (args))) trong khi cond true và trả về chuỗi kết quả một phần

function[arg] được áp dụng trên một hàm có nhiều hơn một đối số sẽ tạo ra một phép chiếu (ứng dụng một phần)

Chúng ta có thể đặt tên cho các đối số, nhưng các tên ẩn là x, y, z

{y-x x bin y}[*+60(|+\)\1 0]khai báo một lambda với args x, y với phép chiếu một phần (arg x là chuỗi sê-ri, tính toán là * + 60 (| +) \ 1 0). x đại diện cho các giá trị của Wikipedia và y là số cần xử lý. Tìm kiếm nhị phân (bin) được sử dụng để xác định chỉ mục của số lượng lớn hơn <= y ( x bin y) và trừ giá trị tương ứng của x.

Để tính toán sản phẩm từ việc bán lại một phần, chúng tôi đảo ngược chúng và tính toán sự khác biệt của từng cặp ( -':|), bỏ số đầu tiên ( 1_vì là 0) và nhân với ( */).

Nếu chúng ta quan tâm đến tổng tích lũy, mã là như nhau, nhưng với +/thay vì */. Chúng tôi cũng có thể sử dụng bất kỳ toán tử diadic nào khác thay vì + hoặc *

Về hiệu quả thực hiện

Tôi biết rằng trong cuộc thi này hiệu quả không phải là một vấn đề. Nhưng trong vấn đề này, chúng ta có thể dao động từ chi phí lineal đến chi phí theo cấp số nhân, vì vậy tôi tò mò về nó.

Tôi đã phát triển một phiên bản thứ hai (chiều dài 48 Byte không bao gồm nhận xét) và lặp lại các trường hợp thử nghiệm pin 1000 lần trên cả hai phiên bản.

f:*+60(|+\)\1 0;m:{*/1_-':|(0<){x-f f bin x}\x}    /new version

thời gian thực hiện là: phiên bản gốc 0'212 seg, phiên bản mới 0'037 seg

Phiên bản gốc tính toán fftimeaci serie một lần cho mỗi ứng dụng chức năng; phiên bản mới tính toán MySpace chỉ một.

Trong cả hai trường hợp, tính toán sê-ri sử dụng đệ quy đuôi

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.