การจัดทำดัชนีหมายเลข Fibonacci แบบขยาย


21

คุณอาจเคยได้ยินหมายเลขฟีโบนักชี คุณรู้ไหมว่าลำดับเลขจำนวนเต็มที่ขึ้นต้นด้วย1, 1จากนั้นแต่ละหมายเลขใหม่คือผลรวมของสองอันสุดท้าย?

1 1 2 3 5 8 13...

และอื่น ๆ ความท้าทายเกี่ยวกับตัวเลขฟีโบนักชีเป็นที่นิยมอย่างมากในรอบนี้ แต่ใครจะบอกว่าหมายเลขฟีโบนักชีต้องเริ่มด้วยกัน1, 1? ทำไมพวกเขาไม่สามารถเริ่มต้นด้วย0, 1? เอาล่ะเรากำหนดใหม่พวกเขาเพื่อเริ่มต้นที่ 0:

0 1 1 2 3 5 8 13...

แต่ ... เราไม่ต้องหยุดตรงนี้! หากเราสามารถเพิ่มตัวเลขสองตัวสุดท้ายเพื่อรับหมายเลขถัดไปเราสามารถลบหมายเลขแรกจากตัวเลขที่สองเพื่อเติมตัวเลขใหม่ ดังนั้นจึงอาจเริ่มต้นด้วย1, 0:

1 0 1 1 2 3 5 8 13...

เราสามารถจบลงด้วยการปฏิเสธ:

-1 1 0 1 1 2 3 5 8 13...

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

13 -8 5 -3 2 -1 1 0 1 1 2 3 5 8 13...

ขอเรียกชุดนี้ "หมายเลข Fibonacci ขยาย" หรือEFN เนื่องจากไม่มีจำนวนลบที่ชัดเจนในการเริ่มต้นชุดนี้เราจะบอกว่า0ปรากฏที่0หมายเลข Fibonacci ปกติขยายเข้าสู่ดัชนีบวกและตัวเลขลบ Fibonacci (ลบครึ่ง) ในดัชนีลบอย่างเช่น:

Indices: ...-7  -6 -5  -4 -3  -2 -1  0  1  2  3  4  5  6  7 ...
Values:  ...13  -8  5  -3  2  -1  1  0  1  1  2  3  5  8  13...

สิ่งนี้นำไปสู่ความท้าทายในปัจจุบัน:

รับจำนวนเต็มNส่งคืนดัชนีทุกตัวที่Nปรากฏในซีรีย์EFN

ข้อสังเกตแบบสุ่มในงานนี้:

  • 1ปรากฏขึ้นอีกครั้งในEFNกว่าจำนวนอื่น ๆ[-1, 1, 2]: จะไม่มีหมายเลขปรากฏในมากกว่า 3 แห่ง

  • หมายเลข Fibonacci ทุกอัน> 1 จะปรากฏขึ้นหนึ่งครั้ง (3, 8, 21, ฯลฯ ) หรือสองครั้ง (2, 5, 13, ฯลฯ )

ชี้แจงกฎ:

  • หากabs(N)ไม่ใช่หมายเลขฟีโบนักชีหมายเลขนั้นจะไม่ปรากฏในซีรีย์EFNดังนั้นคุณจะต้องไม่แสดงผลใด ๆ / คอลเลกชันว่างเปล่าถ้าเป็นไปได้หรือถ้าเป็นไปไม่ได้ในภาษาของคุณคุณสามารถส่งออกค่าที่ไม่ใช่ตัวเลข
  • หากNปรากฏในหลาย ๆ ที่ในEFNเอาต์พุตของคุณไม่จำเป็นต้องเรียงลำดับ แม้ว่าแต่ละดัชนีจะต้องปรากฏอย่างแน่นอนครั้งเดียว
  • แม้ว่าความท้าทายส่วนใหญ่จะช่วยให้คุณเลือกได้ว่าคุณต้องการใช้การจัดทำดัชนีแบบ 1 หรือ 0 ตามความท้าทายนี้ต้องใช้การจัดทำดัชนีที่อธิบายไว้ (ที่ 0 ปรากฏที่ 0)
  • คุณสามารถนำ I / O ผ่านรูปแบบมาตรฐานใด ๆ

กรณีทดสอบ

-13: []
-12: []
-11: []
-10: []
-9: []
-8: [-6]
-7: []
-6: []
-5: []
-4: []
-3: [-4]
-2: []
-1: [-2]
0: 0
1: [-1, 1, 2]
2: [-3, 3]
3: [4]
4: []
5: [-5, 5]
6: []
7: []
8: [6]
9: []
10: []
11: []
12: []
13: [-7, 7]

และกรณีทดสอบที่ใหญ่กว่า:

89: [-11, 11]
1836311903: [46]
10000: []
-39088169: [-38]

ตามปกติคำตอบที่สั้นที่สุดในจำนวนไบต์ชนะ!


ที่เกี่ยวข้องแม้ว่าจะไม่ซ้ำกันเนื่องจากมันไม่ต้องการการจัดการเชิงลบหรือตัวเลขที่ไม่ใช่ฟีโบนักชี
DJMcMayhem

12
ยังมีอีกเหตุผลที่ดีที่หมายเลขดัชนีฟีโบนักชีควรได้รับการจัดทำดัชนีเสมอเพื่อให้ $ F_0 = 0 $ แม้เมื่อใช้หมายเลขฟีโบนักชีบวกเท่านั้น นั่นคือการจัดทำดัชนีที่อนุญาตคุณสมบัติที่สวยงามนี้: ถ้า $ k $ หาร $ n $ ดังนั้น $ F_k $ จะแบ่ง $ F_n $
Greg Martin

คำตอบ:


9

Haskell , 78 ไบต์

บันทึกได้ 4 ไบต์ด้วย nimi

a#b=a:b#(a-b)
f 0=[0]
f a=do{(i,x)<-zip[0..a*a+1]$0#1;[-i|x==a]++[i|abs x==a]}

ลองออนไลน์!

ครั้งแรกที่เราตั้งค่า(#), (#)ใช้เวลาสองพารามิเตอร์aและbและผลตอบแทนรายการที่เริ่มต้นด้วยและตามมาด้วยa b#(a-b)สิ่งนี้สร้างรายการไม่สิ้นสุด แต่เนื่องจาก Haskell ขี้เกียจเราไม่จำเป็นต้องกังวลเกี่ยวกับมันวนซ้ำตลอดไป สิ่งนี้ใช้งานได้จริงในการสร้างลำดับ Fibonacci ก่อนคู่ที่แน่นอน ตัวอย่างเช่น(0#1)จะเป็นรายการหมายเลข Fibonacci ทั้งหมดที่มีดัชนีติดลบ

fจากที่นี่เราทำให้ fรับอาร์กิวเมนต์aซึ่งเป็นตัวเลขที่เราพยายามหาตามลำดับ ที่นี่เราใช้doสัญกรณ์เพื่อทำความเข้าใจกับรายการ เราเริ่มต้นด้วยการเป็นครั้งแรกa*a+1องค์ประกอบของรายการ10#1 เนื่องจากฟังก์ชั่นa*a+1เติบโตเร็วกว่าอินเวอร์สของลำดับฟีโบนักชีเราจึงมั่นใจได้ว่าถ้าเราตรวจสอบภายในขอบเขตนี้เราจะพบผลลัพธ์ทั้งหมด สิ่งนี้ทำให้เราไม่สามารถค้นหารายการที่ไม่มีที่สิ้นสุด จากนั้นสำหรับแต่ละค่าxและดัชนีiถ้าx==aเราพบaในครึ่งลบของลำดับเราจึงส่งคืน-iและถ้าabs x==aเรากลับiเช่นกันเพราะค่าสัมบูรณ์ของครึ่งลบนั้นเป็นครึ่งบวกดังนั้นเราจึงพบมันที่นั่น

เนื่องจากสิ่งนี้ทำให้รายการ[0,0]สำหรับ0เราฮาร์ดโค้ดผลลัพธ์ที่ถูกต้องสำหรับอันนั้น

1: เคล็ดลับนี้จะนำมาจากคำตอบที่สะอาดΟurous' การเร่งความเร็วแบบเดียวกับที่นี่แทนที่a*a+1ด้วยabs a+1เพื่อประหยัดเวลา


การแทนที่uด้วยเครื่องหมายa#b=a:b#(a-b)บวก0#1จะช่วยประหยัดไบต์: ลองออนไลน์!
nimi

@nimi จริง ๆ แล้วบันทึก 4 ไบต์ลิงค์ tio ของคุณมีช่องว่างเพิ่มเติม 3
ข้าวสาลีตัวช่วยสร้าง

5

สะอาด , 132 120 109 ไบต์

import StdEnv
g n|n<2=n=g(n-1)+g(n-2)
?k=[e\\p<-[0..k*k+1],e<-if(isOdd p)([~p,p]%(0,k))[p*sign k]|g p==abs k]

ลองออนไลน์!

g :: Int -> Intเป็นฟังก์ชั่นฟีโบนักชี
? :: Int -> [Int]เพียงดัชนีเป็นองค์ประกอบของ EFN ภายในของk^2+10

สำหรับรุ่นที่วิ่งในจำนวนเงินที่มีเหตุผลของเวลาเปลี่ยนแปลงไปk*k+1abs k+1


1
รายการเคล็ดลับความเข้าใจนั้นค่อนข้างเรียบร้อย! บันทึก 14 ไบต์บนคำตอบของฉัน
ข้าวสาลี Wizard




1

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

[1-9].*
$*
(-)?(\b1|(?>\3?)(\2))*(1)$|(0)?.*
$5$1$4$4$#2$*
-1(11)+$

^1(11)+$
-$&,$&
1+
$.&
^2$
-1,1,2

ลองออนไลน์! คำอธิบาย:

[1-9].*
$*

แปลงเป็น unary เว้นแต่อินพุตจะเป็นศูนย์

(-)?(\b1|(?>\3?)(\2))*(1)$|(0)?.*
$5$1$4$4$#2$*

คำนวณดัชนี Fibonacci ของค่าสัมบูรณ์ แต่ถ้าจำนวนนั้นไม่ใช่ตัวเลข Fibonacci ให้ลบทิ้งเว้นแต่ว่าจะเป็นศูนย์ สิ่งนี้ใช้ regex การทดสอบฟีโบนักชีของ @ MartinEnder

-1(11)+$

ลบหมายเลขลบที่มีค่าสัมบูรณ์เป็นเลขฟีโบนักชีคี่

^1(11)+$
-$&,$&

เพิ่มดัชนีติดลบสำหรับตัวเลขฟีโบนักชีบวก

1+
$.&

แปลงเป็นทศนิยม

^2$
-1,1,2

1เพิ่มดัชนีพิเศษสำหรับ


1

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

;╗3*;±kSix⌠;;AF@;1&@0>*YτD(s**╜=⌡░

แรงเดรัจฉานบันทึกวัน

คำอธิบาย:

;╗3*;±kSix⌠;;AF@;1&@0>*YτD(s**╜=⌡░
;╗                                  save a copy of the input (let's call it N) to register 0 (the main way to get additional values into functions)
  3*;±                              -3*N, 3*N
      kSi                           push to list, sort, flatten (sort the two values on the stack so that they are in the right order for x)
         x                          range(min(-3*N, 3*N), max(-3*N, 3*N))
          ⌠;;AF@;1&@0>*YτD(s**╜=⌡░  filter (remove values where function leaves a non-truthy value on top of the stack):
           ;;                         make two copies of parameter (let's call it n)
             AF                       absolute value, Fib(|n|)
               @;                     bring a copy of n to the top of the stack and make another copy
                 1&                   0 if n is divisible by 2 else 1
                   @0>                1 if n is negative else 0 (using another copy of n)
                      *               multiply those two values (acts as logical AND: is n negative and not divisible by 2)
                       YτD            logical negate, double, decrement (maps [0, 1] to [1, -1])
                          (s          sign of n (using the last copy)
                            **        multiply Fib(|n|), sign of n, and result of complicated logic (deciding whether or not to flip the sign of the value for the extended sequence)
                              ╜=      push value from register 0, equality comparison (1 if value equals N else 0)

ลองออนไลน์!




0

05AB1E , 36 ไบต์

x*ÝʒÅfIÄQ}Ii®šë1KIdiÐ`ÉiD(ì}ëD`Èi(ë¯

จะต้องมีวิธีที่ดีกว่า .. >.> มีหก (หรือเจ็ดถ้าเรารวม0) สถานการณ์ที่แตกต่างกันสำหรับความท้าทายนี้และมันฆ่าฉัน ..

ลองมันออนไลน์หรือตรวจสอบกรณีทดสอบทั้งหมด

คำอธิบาย:

x            # Create a list in the range [0, (implicit) input * input * 2]
   ʒ     }     # Filter this list by:
    Åf         #  Where the Fibonacci value at that index
      IÄQ      #  Is equal to the absolute value of the input
Ii             # If the input is exactly 1:
  ®š           #  Prepend -1 to the list
ë              # Else:
 1K            #  Remove all 1s (only applies to input -1)
 Idi           #  If the input is non-negative:
    Ð`Éi   }   #   If the found index in the list is odd:
        D    #    Prepend its negative index to the list
   ë           #  Else (the input is negative):
    Di       #   If the found index in the list is even:
        (      #    Negate the found index
       ë       #   Else (found index is odd):
        ¯      #    Push an empty array
               # (Output the top of the stack implicitly as result)

ตัวอย่างทีละขั้นตอน:

Input:  Filtered indices:  Path it follows (with actions) and result:

-8      [6]                NOT 1 → neg → even index → negate index: [-6]
-5      [5]                NOT 1 → neg → odd index → push empty array: []
-1      [1,2]              NOT 1 → (remove 1) neg → even remaining index: negate index: [-2]
0       [0]                NOT 1 → even index → negate index: [0]    
1       [1,2]              1 → prepend -1: [-1,1,2]
5       [5]                NOT 1 → non-neg → odd index → Prepend neg index: [-5,5]
8       [6]                NOT 1 → non-neg → even index → (nothing): [6]


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