ผลิตภัณฑ์ Fibonacci


13

คุณสามารถแยกตัวเลขที่มากกว่า 0 เป็นผลรวมที่ไม่ซ้ำกันของตัวเลขฟีโบนักชีบวก ในคำถามนี้เราทำได้โดยการลบจำนวนฟีโบนัชชีบวกที่ใหญ่ที่สุดซ้ำไปซ้ำมา เช่น:

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

ตอนนี้ฉันเรียกผลิตภัณฑ์ Fibonacciว่าเป็นรายการเดียวกันกับข้างบน แต่ด้วยการเพิ่มถูกแทนที่ด้วยการคูณ ตัวอย่างเช่นf(100) = 89 * 8 * 3 = 2136.

เขียนโปรแกรมหรือฟังก์ชั่นที่ให้จำนวนเต็มบวกnส่งคืนผลคูณของฟีโบนักชีของตัวเลขนั้น


Testcases:

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
คำสั่งไม่ถูกต้องมาก เช่นสามารถย่อยสลายเป็น2 -1 + 3คำแถลงที่ถูกต้องของทฤษฎีบทของ Zeckendorf คือตัวเลขจำนวนฟีโบนักชีบวกสามารถแยกย่อยได้อย่างไม่เหมือนใครซึ่งเป็นผลรวมของตัวเลขฟีโบนัชชีแบบไม่ต่อเนื่องพร้อมดัชนีค่าบวก
Peter Taylor

1
@PeterTaylor ฉันไม่พิจารณาตัวเลขฟีโบนักชีเชิงลบส่วนหนึ่งของซีรี่ส์สำหรับคำถามนี้ ติดต่อกันหรือไม่สำคัญเฉพาะเมื่อคุณต้องการดัชนีเราไม่สนใจเกี่ยวกับดัชนีสำหรับคำถามนี้
orlp

1
ฉันไม่ได้บอกว่าคุณควรเปลี่ยนคำถามเพื่อสนับสนุนตัวเลขฟีโบนักชีเชิงลบ: ฉันกำลังบอกว่าคุณควรแก้ไขให้ชัดเจนเกี่ยวกับสมมติฐานที่คุณทำ
Peter Taylor

1
@ หรือติดต่อกันหรือไม่สำคัญมากเนื่องจากรูปแบบที่แตกต่างกันสองแบบจะให้ผลิตภัณฑ์ที่แตกต่างกันสองแบบ คุณได้กล่าวถึงปัญหาในลักษณะที่โดยปริยายแล้วโดยปริยายออกข้อกำหนด Fibonacci ติดต่อกันดังนั้นจึงไม่มีอะไรต้องกังวลเกี่ยวกับที่นั่น
ฮอบส์

2
(โดยเฉพาะ: F (n) และ F (n + 1) ไม่สามารถปรากฏในเอาต์พุตได้เนื่องจากอัลกอริธึมรับประกันว่าก่อนที่จะพิจารณาพวกเขาส่วนที่เหลือนั้นน้อยกว่า F (n + 2) = F (n) + F (n + 1))
hobbs

คำตอบ:


5

เยลลี่ , 16 15 ไบต์

Rf1+С¤ṪạµÐĿIAP

ไม่รวดเร็วหรือเป็นมิตรกับหน่วยความจำ แต่มีประสิทธิภาพเพียงพอสำหรับทุกกรณีทดสอบ ลองออนไลน์!

มันทำงานอย่างไร

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
ดูเหมือนว่าจะเป็นเรื่องใหญ่เดนนิส
orlp


5

Perl, 69 63 + 4 ( -pl61แฟล็ก) = 67 ไบต์

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

โดยใช้:

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

Ungolfed:

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

ไอดีโอ


คำอธิบายควรจะพูดถึงฐานแปดที่061เข้ารหัส ASCII '1'สำหรับตัวละคร แฮ็คที่ดีที่จะใช้$\เพื่อพิมพ์ให้ใกล้ฟรี
Peter Cordes

2

JavaScript (ES6), 78 42 ไบต์

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

คำตอบของพอร์ต @ Sp3000 เวอร์ชัน 78 ไบต์เดิม:

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 ไบต์

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

คาดว่าหมายเลขอินพุตจะแสดงบนสแต็กเมื่อเริ่มต้นโปรแกรม

สร้างลำดับ Fibonacci ( f0, f1, f2, ..., fn) บนสแต็กจนกระทั่งถึงจำนวนที่มากกว่าค่าอินพุต ( i) จากนั้นด้วยผลิตภัณฑ์ ( p) เริ่มต้นไปที่1...

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

ลองออนไลน์!


ดี! ฉันขอแนะนำให้คุณโพสต์ลิงก์โดยใช้คอมไพเลอร์ออนไลน์
Luis Mendo


1

Pyth, 24 ไบต์

W=-QeaYh.WgQeH,eZsZ1;*FY

ลองใช้ออนไลน์: การสาธิตหรือชุดทดสอบ

คำอธิบาย:

Q ถูกกำหนดด้วยหมายเลขอินพุต

ส่วนh.WgQeH,eZsZ1คำนวณจำนวนฟีโบนักชีที่ใหญ่ที่สุดซึ่งเล็กกว่าหรือเท่ากับQ

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

ดังนั้นถ้าQ = 10มันสร้างตัวเลข / คู่:

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

ส่วนที่เหลือของรหัสคำนวณพาร์ติชันและคูณตัวเลขเข้าด้วยกัน:

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

เห็นได้ชัดว่ามีวิธีแก้ปัญหาที่สั้นกว่า*FhfqQsTyeM.u,eNsNQ1มากมาย


1

Haskell, 44 ไบต์

Yay สำหรับการเรียกซ้ำซึ่งกันและกัน:

(a&b)c|c<1=1|b>c=a*f(c-a)|d<-a+b=b&d$c
f=0&1
  • a คือหมายเลข Fibonacci ก่อนหน้า
  • b คือหมายเลข Fibonacci ปัจจุบัน
  • c คืออินพุต
  • f เป็นฟังก์ชั่นที่ต้องการ

หักกอล์ฟ:

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

1

ที่จริงแล้ว 22 ไบต์

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

ลองออนไลน์!

คำอธิบาย:

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

จริงๆแล้วมีการเข้ารหัสของตัวเอง? ฉันนับ 35 ไบต์ใน 22 ตัวอักษร mothereff.in/…
cat

1
@cat เหมือนอย่างจริงจังจะใช้ CP437
Mego

1

Javascript (ES6) 134 106 92 ไบต์

ขอบคุณ @cat สำหรับการหาพื้นที่

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

เพียงเวอร์ชันที่ไม่มีการเพิ่มประสิทธิภาพที่ทำในโทรศัพท์ของฉันฉันเอามันลงมาเมื่อฉันกลับถึงบ้าน ยินดีต้อนรับไอเดีย


มีหนึ่งช่องว่างที่ยอดเยี่ยม : P
cat

1

ผลตอบแทน 44 ไบต์

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

Try it here.

แลมบ์ดานิรนามที่ไม่มีประสิทธิภาพอย่างน่าประหลาดใจซึ่งทิ้งผลไว้ใน Stack2 การใช้งาน:

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

หมายเหตุ: ␌และ␁เป็นตัวยึดสำหรับตัวอักษรของตนไม่สามารถพิมพ์: ฟีดในแบบฟอร์มและการเริ่มต้นของหัวเรื่อง

คำอธิบาย

[                                           ]  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

ฉันนับ 46 ไบต์ใน 42 ตัวอักษร ถ้า RETURN ใช้การเข้ารหัสพิเศษบางอย่างมันควรเป็น 42 ไบต์ใน 42 ตัวอักษร แต่ดูเหมือนว่าจะเป็น Unicode ดังนั้นมันจึงเป็น 46
cat

ที่จริงแล้วฉันเพิ่งรู้ว่าฉันลืมที่จะใส่ใน unprintables บาง
Mama Fun Roll

ฉันต้องการกล้องจุลทรรศน์เพื่อบอกว่ามันคืออะไรดังนั้นฉันจึงเชื่อมโยงมันเข้ากับคุณ : D (ฉันไม่สามารถบอกได้ว่ามันคือ SOH หรือ BOM)
แมว

0

PHP, 119 ไบต์

รหัส (ห่อสองบรรทัดสำหรับการอ่าน)

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;

บรรทัดแรกจะคำนวณ$fตัวเลข Fibonacci ที่เล็กกว่า$n(อาร์กิวเมนต์ที่ให้ไว้ในบรรทัดคำสั่ง) บรรทัดที่สองคำนวณปัจจัย Fibonacci (โดยลบ) $oและคูณพวกเขาในการคำนวณผลิตภัณฑ์ใน

เตรียมรหัสด้วย<?php(โดยทางเทคนิคไม่ใช่ส่วนหนึ่งของโปรแกรม) วางไว้ในไฟล์ ( fibonacci-factors.php) จากนั้นเรียกใช้เป็น:

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

php -d error_reporting=0 -r '... code here ...' 100หรือเรียกใช้โดยใช้

รหัส ungolfed และชุดทดสอบที่สามารถพบได้บน Github


0

Q, 47 ไบต์

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

ทดสอบ

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

อ่านมันเป็นคู่ (i, map (m, i)) โดยที่ m คือฟังก์ชันการคำนวณและ i เป็น args ที่ต่างกัน

เขียน

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

คำอธิบาย

n funtion\arg ใช้ฟังก์ชั่น (ฟังก์ชั่น (ฟังก์ชั่น (ฟังก์ชั่น (... ฟังก์ชั่น (args))) n ครั้ง (ภายในใช้เรียกซ้ำทัล) และส่งกลับลำดับของผลลัพธ์เราคำนวณ 60 รายการแรกของซีรีส์ Fibonnaci เป็น*+60(|+\)\1 0ในกรณีนั้นฟังก์ชั่นคือ | +): + \ นำไปใช้กับลำดับคำนวณผลรวมบางส่วน (อดีต + \ 1 2 3 คือ 1 3 6) และ | ฝืน seq ดังนั้น 'การวนซ้ำ' แต่ละครั้งเราคำนวณผลรวมบางส่วนของจำนวนฟีโบนักชีสองก่อนหน้านี้และคืนค่าบางส่วน ผลรวมย้อนกลับ60(|+\)\1 0สร้างลำดับ 1 0, 1 1, 2 1, 3 2, 5 3, 8 5, 13 8, 21 13, ... *+นำไปใช้กับผลการพลิกนี้ (traspose) มันและใช้ครั้งแรกผลที่ได้คือลำดับ 1 1 2 3 5 8 13 21 34 55 ..

(cond)function\args ใช้ฟังก์ชัน (function (.. function (args))) ในขณะที่ cond true และส่งคืนลำดับของผลลัพธ์บางส่วน

function[arg] ใช้กับฟังก์ชั่นที่มีมากกว่าหนึ่งอาร์กิวเมนต์สร้างการฉายภาพ (แอพพลิเคชั่นบางส่วน)

เราสามารถตั้งชื่อให้กับ args ได้ แต่ชื่อโดยนัยคือ x, y, z

{y-x x bin y}[*+60(|+\)\1 0]ประกาศแลมบ์ดากับ args x, y ด้วยการฉายบางส่วน (หาเรื่อง x คือฟีโบนักชีซีรีส์คำนวณเป็น * + 60 (| +) \ 1 0) x แทนค่าฟีโบนักชีและจำนวนที่ประมวลผล การค้นหาแบบไบนารี (bin) ใช้เพื่อค้นหาดัชนีของหมายเลขx bin yฟีโบนักชีมากกว่า <= y ( ) และแทนที่ค่าที่สอดคล้องกันของ x

ในการคำนวณผลิตภัณฑ์จากตัวต้านทานบางส่วนเราจะทำการย้อนกลับและคำนวณความแตกต่างของแต่ละคู่ ( -':|) ให้วางอันแรก ( 1_เพราะเป็น 0) และคูณด้วย ( */)

ถ้าเรามีความสนใจในผลรวมสะสมรหัสเดียวกัน แต่มีแทน+/ */นอกจากนี้เรายังสามารถใช้ตัวดำเนินการ diadic อื่นแทน + หรือ *

เกี่ยวกับประสิทธิภาพการดำเนินการ

ฉันรู้ว่าในการแข่งขันครั้งนี้ไม่มีปัญหา แต่ในปัญหานี้เราสามารถหาได้ตั้งแต่ต้นทุนเชิงเส้นถึงต้นทุนเอ็กซ์โปเนนเชียล

ฉันพัฒนารุ่นที่สอง (ความยาว 48 ไบต์ไม่รวมข้อคิดเห็น) และกรณีทดสอบซ้ำแบตเตอรี่ 1,000 ครั้งทั้งสองรุ่น

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

เวลาดำเนินการคือ: เวอร์ชันดั้งเดิม 0'212 seg, เวอร์ชันใหม่ 0'037 seg

เวอร์ชั่นต้นฉบับจะคำนวณ fibbonaci serie หนึ่งครั้งต่อแอปพลิเคชั่น; เวอร์ชั่นใหม่คำนวณ fibonacci เพียงอันเดียว

ในการคำนวณทั้งสองกรณีของชุด fibonacci ใช้การเรียกซ้ำแบบหาง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.