จำนวนนี้แอบ Fibonacci หรือไม่?


23

พื้นหลัง

พวกคุณส่วนใหญ่รู้ว่าหมายเลขฟีโบนักชีคืออะไร บางท่านอาจจะรู้ว่าจำนวนเต็มบวกทั้งหมดสามารถแสดงเป็นผลรวมของหนึ่งหรือตัวเลข Fibonacci ที่แตกต่างกันมากขึ้นตามZeckendorf ทฤษฎีบท หากจำนวนเงื่อนไขในการแทนค่า Zeckendorf ที่ดีที่สุดของจำนวนเต็มnนั้นเป็นหมายเลขฟีโบนักชีเราจะเรียกnฟีโบนักชี "แอบ"

ตัวอย่างเช่น:

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

หมายเหตุ

  • ตัวแทน Zeckendorf ที่ดีที่สุดสามารถพบได้โดยใช้อัลกอริทึมโลภ เพียงใช้จำนวนฟีโบนักชีที่ใหญ่ที่สุด <= n และลบออกจาก n จนกว่าคุณจะถึง 0
  • หมายเลข Fibonacci ทั้งหมดสามารถแสดงเป็นผลรวมของ 1 หมายเลข Fibonacci (ตัวมันเอง) เนื่องจาก 1 คือหมายเลขฟีโบนักชีหมายเลขฟีโบนักชีทั้งหมดจึงเป็นฟีโบนักชีอย่างลับๆ

ท้าทาย

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

อินพุต

คุณสามารถป้อนข้อมูลในรูปแบบที่เหมาะสม คุณอาจสันนิษฐานว่าการป้อนข้อมูลจะเป็นจำนวนเต็มบวกเดียว

เอาท์พุต

เอาต์พุตหนึ่งในสองผลลัพธ์ที่แตกต่างกันสำหรับการป้อนข้อมูลว่าเป็นฟีโบนักชีหรือไม่ ตัวอย่าง ได้แก่True/ False, 1/ 0, ฯลฯ

เกณฑ์การให้คะแนน

นี่คือดังนั้นคำตอบที่สั้นที่สุดในจำนวนไบต์ชนะ! ช่องโหว่มาตรฐานเป็นสิ่งต้องห้าม

กรณีทดสอบ

Truthy (secretly Fibonacci)
1
2
4
50
140
300099

Falsey (NOT secretly Fibonacci)
33
53
54
139
118808

6
นี่หมายความว่าพวกเขาอยากรู้อยากเห็นหรือไม่?
วิน

2
ในกรณีที่มีการใช้งานกับทุกคน: ผลรวมที่ดีที่สุดคือโซลูชันที่ไม่ซ้ำใครซึ่งไม่ได้ใช้หมายเลขฟีโบนักชีต่อเนื่องกันสองหมายเลข
kasperd

2
@kasperd คุณถูกต้องแล้วซึ่งสมเหตุสมผลถ้าคุณคิดเกี่ยวกับมัน หากวิธีการแก้ปัญหามีตัวเลขฟีโบนักชีสองหมายเลขติดต่อกันพวกเขาสามารถรวมเข้าด้วยกันเพื่อสร้างหมายเลขถัดไป หากวิธีการแก้ปัญหาของคุณมี 5 และ 8 มันจะดีที่สุดน้อยกว่าการมี 13 เดียว
Cowabunghole

@ Cowabunghole นั่นคือสัญชาตญาณ หลักฐานเต็มรูปแบบมีความซับซ้อนกว่านั้นเล็กน้อย หากโซลูชันมี 5, 8 และ 13 อยู่แล้วคุณจะต้องเพิ่ม 8 + 13 ไม่ใช่ 5 + 8 และต้องพิสูจน์ทิศทางอื่นด้วยเช่นกัน
kasperd

คำตอบ:



8

Python 2 , 77 ไบต์

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

ลองออนไลน์!

สิ่งนี้ใช้ประโยชน์จากทฤษฎีบทว่าคำอธิบายทั้งสองของOEIS A003714นั้นเทียบเท่ากัน:

n=F(ผม1)+F(ผม2)++F(ผมk)nna(n)=2ผม1+2ผม2++2ผมk1's

zn

จากนั้นก็ยังคงตรวจสอบว่าz[n]เป็นหมายเลขฟีโบนักชีหรือz[z[n]] == 1ไม่

n2+1


คุณสามารถตัดไบต์ที่สองโดยการเอา backticks bin(x)รอบ นอกจากนี้คุณยังสามารถลบหนึ่งโดยการเปลี่ยนไปrange(n*n+1) range(n<<n)(สมมติว่า 0 ไม่ถูกต้อง)
nedla2004

ฉันไม่รู้ว่ากำลังคิดอะไรกับ backticks อยู่bin(x)ฮ่าฮ่า และ, หืมมม, 1<<nมีวิธีมากเกินพอ แต่ฉันต้องการให้รันไทม์ที่ไม่ใช่ทางดาราศาสตร์
Lynn

พอใช้ฉันคิดว่าความสามารถในการเรียกใช้รหัสอาจเป็นคุณลักษณะที่สำคัญ :)
nedla2004

6

เยลลี่ 15 ไบต์

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

ลิงก์ monadic ยอมรับจำนวนเต็มที่ไม่เป็นลบซึ่งให้ผล1ถ้า "Secretly Fibonacci" และเป็น0อย่างอื่น

ลองออนไลน์! (ไม่มีประสิทธิภาพมากเกินไปสำหรับกรณีทดสอบที่ใหญ่กว่า)

อย่างไร?

‘ÆḞ€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 ไบต์

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

ลองออนไลน์!

-3 ไบต์: เปลี่ยนในขณะที่วนรอบเป็นสำหรับ (ขอบคุณOlivier Grégoire )
-6 ไบต์: สลับกลับไปใช้ตัวแปรเริ่มต้น b และ c นอกลูป (ขอบคุณKevin Cruijssen )
-17 ไบต์: เปลี่ยนเงื่อนไขในลูปที่สองเพื่อย้ายถ้า out of loop และรวมกับ return, b และ c นำมาใช้ซ้ำในลูปสุดท้าย (ขอบคุณraznagul )

Ungolfed:

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;จะช่วยให้คุณประหยัด 3 ไบต์
Olivier Grégoire

1
115 ไบต์ ฉันออกทั้งหมด{}-brackets ของลูปของคุณและใส่ทุกอย่างในfor-loops นอกจากนี้ผมเพิ่มตัวแปรrซึ่งเราตั้งค่าให้1คุณในการกลับมาและในตอนท้ายเพื่อให้คุณมีเพียงหนึ่งif(e==n) return
Kevin Cruijssen

โทรดีทั้ง ฉันพยายามที่จะเปลี่ยนในขณะที่ห่วงเพื่อและอย่างใดพลาดวิธีที่ง่ายที่จะทำ การมีตัวแปรแยกต่างหากเพื่อผลตอบแทนก็ดีขึ้นเช่นกัน
เมียร์แค

1
โดยการเปลี่ยนสภาพในวงที่สองเพื่อe<nให้คุณสามารถย้ายifไปหลังจากวนและ consequentlly รวมกับreturnสำหรับ101 ไบต์
raznagul

1
คุณสามารถบันทึกอีก 3 ไบต์โดยการนำbและcในวงที่ผ่านมาและการถอดและd e
raznagul

4

Perl 6 , 58 ไบต์

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

ลองออนไลน์!

1, &[+] ... * > $_ เป็นเพียงลำดับ Fibonacci หยุดในสถานที่ไม่สิ้นสุดสะดวก (หมายเลขอินพุต)

$_, { $^n - (1, &[+] ...^ * > $n).tail } ... 0คือลำดับของตัวเลขเริ่มต้นด้วยหมายเลขอินพุตและแต่ละองค์ประกอบที่ต่อเนื่องที่ได้รับจากการลบจำนวนฟีโบนักชีที่ใหญ่ที่สุดที่น้อยกว่าหรือเท่ากับองค์ประกอบก่อนหน้าจากองค์ประกอบก่อนหน้า ลำดับจะสิ้นสุดเมื่อ0ถึง ตัวอย่างเช่นถ้า$_เป็นแล้วนี้คือลำดับ140140, 51, 17, 4, 1, 0

การลบหนึ่งจากลำดับนี้ถือว่าเป็นตัวเลขความยาวและความแตกต่างคือจำนวนของหมายเลขฟีโบนักชีซึ่งรวมเข้าด้วยกันให้ป้อนหมายเลข จากนั้นหมายเลขนี้จะถูกตรวจสอบความเป็นสมาชิกในลำดับ Fibonacci แรก


ฉันไม่เคยเห็นกลอุบายนั้น&[+]มาก่อน! Nice ประหยัดโดยไม่ต้องกำหนดคำสองคำแรก
Jo King

1
51 bytesโดยกำหนดลำดับ Fibonacci ให้กับฟังก์ชั่นและการเปลี่ยนแปลงอื่น ๆ สองสามอย่าง
Jo King

คำตอบ JavaScript ของพอร์ตของ l4m2 ขนาด 50 ไบต์
nwellnhof

@nwellnhof Ha, ฉันมีสิ่งเดียวกันค่อนข้างมากยกเว้นความแตกต่างเล็กน้อย
Jo King

3

Perl 6 , 48 ไบต์

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

ลองออนไลน์!

แปลงอินพุตเป็นรายการของตัวแทน Zeckendorf ซ้ำ ๆ จนกระทั่งถึงหมายเลขเดียวแล้วตรวจสอบว่าความยาวของลำดับน้อยกว่า 4 หรือไม่

ฟังก์ชัน Zenckendorf ที่อยู่ตรงกลางส่วนใหญ่มาจากคำตอบของฌอนด้วยการปรับปรุงสองสามอย่าง

คำอธิบาย:

{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

ตัวอย่างเช่นลำดับสำหรับ2คือ2 1ตั้งแต่2มีหมายเลขฟีโบนักชีแล้ว ลำดับสำหรับ140คือ140 5 1และตั้งแต่ 5 คือหมายเลขฟีโบนักชีสิ่งนี้จะคืนค่าจริง ลำดับสำหรับ33คือ33 4 2 1และเนื่องจาก4ไม่ใช่หมายเลขฟีโบนักชีลำดับจึงมีความยาว 4


3

05AB1E , 14 ไบต์

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

ลองออนไลน์ลองมันออนไลน์ไม่มีชุดทดสอบสำหรับกรณีทดสอบทั้งหมดเนื่องจากcounter_variableไม่สามารถรีเซ็ตเป็น 0 .. ฉันยืนยันด้วยมือทุกอย่างแล้วและถูกต้อง

คำอธิบาย:

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

หมายเหตุ: counter_variableจะเป็น5สำหรับการป้อนข้อมูล139และ6สำหรับการป้อนข้อมูล140เพราะเพื่อให้Δ-loop เพื่อตรวจสอบสแต็คยังคงเหมือนเดิมก็ไม่แน่นอนซ้ำเพิ่มเติม



2

เรติน่า 0.8.2 , 61 ไบต์

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

ลองออนไลน์! ลิงค์มีกรณีทดสอบ คำอธิบาย:

.+
$*

แปลงเป็นเอก

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

นับจำนวนตัวเลขฟีโบนักชีที่ต้องการ

ทางเลือกแรกเกี่ยวข้องกับหมายเลขฟีโบนักชีที่อย่างน้อย 2 ในรอบแรก\2ยังไม่มีอยู่ แต่โชคดีที่มันเป็นทางเลือกดังนั้นเราจึงไม่ต้องจับคู่ \1ไม่ได้มีอยู่ แต่อย่างโชคดีที่เรามีทางเลือก\G.ที่ตรงกับตัวละครตัวเดียวในตอนเริ่มการแข่งขัน ทั้งสอง\2และ\1ใช้ค่า 1

เมื่อผ่านไป\2แล้วมีอยู่ดังนั้นเราจึงพยายามจับคู่ คราวนี้ถ้ามันล้มเหลวแล้ว\1ยังล้มเหลว (เพราะมันมีขนาดใหญ่กว่า\2) แต่ถ้ามันประสบความสำเร็จใน(?>)การป้องกันการย้อนรอยดังนั้นหาก\2การแข่งขัน แต่ไม่ได้เราไม่ได้ลองเพียง\1 \1( \G1ล้มเหลวเสมอเนื่องจากเราได้ผ่านจุดเริ่มต้นของแพตช์ขั้นสูง) ในที่สุดก็\2ใช้ค่าก่อนหน้านี้\1ขณะที่\1รับผลรวมของทั้งสองค่า

เราจึงจับคู่หมายเลขฟีโบนัชชีให้มากที่สุดเท่าที่จะทำได้โดยเพิ่มเมื่อเราไป เนื่องจากผลรวมบางส่วนของลำดับ1, 2, 3, 5...นั้น0, 1, 3, 6, 11...คือ 2 น้อยกว่าตัวเลขฟีโบนักชีเราเสร็จสิ้นโดยการจับคู่ 2 ในตอนท้าย

เห็นได้ชัดว่าไม่สามารถจับคู่ 1 ได้ดังนั้นการสลับจะจัดการกับกรณีนั้น

.+
$*

แปลงเป็นเอก

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

ทดสอบว่านี่คือหมายเลขฟีโบนักชีหรือไม่ สิ่งนี้ใช้แนวคิดเดียวกันกับการทดสอบครั้งแรก แต่ใช้^แทน\Gและเราจำเป็นต้องจับคู่ให้ตรงกันดังนั้นจึงใช้การจับภาพตัวเลือกแทนที่จะเป็นทางเลือกเหมือนกับนักกอล์ฟ

เรติน่า 35 ไบต์

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

ลองออนไลน์! ลิงค์มีกรณีทดสอบ คำอธิบาย:

.+
*

แปลงเป็นเอก

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

นับจำนวนตัวเลขฟีโบนักชีที่ต้องการ (การวนซ้ำทั้งการแปลงและการนับจะช่วยประหยัดทั้งไบต์ในการรับการนับในครั้งแรก)

2}

ทำตามขั้นตอนก่อนหน้ารวมสองครั้ง วิธีนี้ใช้การนับจำนวนฟีโบนัชชีที่จำเป็นในการรวมกับการนับจำนวนฟีโบนัชชี

^1$

ถ้าตัวเลขเป็นฟีโบนักชีอย่างลับ ๆ ผลลัพธ์ก็คือ 1


1

Python 2 , 146 137 ไบต์

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)

ลองออนไลน์!

f () เป็นฟังก์ชันเรียกซ้ำที่ส่งกลับค่าหมายเลข n ฟีโบนักชี นำมาจากคำตอบนี้

g () เป็นฟังก์ชันเรียกซ้ำที่ส่งกลับการแทนค่า Zeckendorf ของจำนวนที่กำหนดเป็นรายการจำนวนเต็ม

เนื่องจากหมายเลขฟีโบนักชีทั้งหมดจะมีความยาวส่งคืนของหนึ่งรายการจาก g (), h () ตรวจสอบว่าความยาวของ g () ของ g (n) == 1

แก้ไข:บันทึกไว้ 9 ไบต์ขอบคุณที่nedla2004 ฉันลืมไปว่า lambdas ไม่ใช่ทางออกที่ดีที่สุดเสมอไป ...


1
138 ไบต์ ฉันส่วนใหญ่เพิ่งสร้างgฟังก์ชั่นเพื่อให้ฉันสามารถกำหนดf(n-1)ตัวแปร คู่การเปลี่ยนแปลงอื่น ๆ จาก==ไป<ที่พวกเขาเหมือนกัน
nedla2004
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.