ค้นหารูปแบบฟีโบนักชี


16

คุณอาจคุ้นเคยกับลำดับฟีโบนักชีที่สองคำแรกเป็น0, 1(หรือบางครั้ง1, 1) และทุกคำหลังจากนั้นคือผลรวมของสองคำก่อนหน้า มันเริ่มเป็นแบบนี้:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

บางครั้งลำดับมีตัวเลขที่มีรูปแบบเฉพาะที่ฉันสนใจ: ความแตกต่างระหว่างคู่ของตัวเลขใด ๆ ที่อยู่ติดกันเหมือนกันกับคู่อื่น ๆ ยกตัวอย่างเช่นในลำดับที่เริ่มต้นด้วย0, 1คำที่ 18 987คือ และ9-8=1 8-7=1ฉันพอใจอย่างอ่อนโยน

ท้าทาย

ให้สองค่าเริ่มต้นF(0)และF(1)ส่งออกทุกตัวเลขในลำดับที่สร้างโดยF(n) = F(n-1) + F(n-2)ที่ตรงกับเกณฑ์ต่อไปนี้:

  • ความแตกต่างระหว่างคู่ของตัวเลขใด ๆ ที่อยู่ติดกันจะเหมือนกับคู่อื่น ๆ
  • มีความยาวอย่างน้อยสามหลัก (ตัวเลข 1 และ 2 หลักไม่น่าสนใจสำหรับรูปแบบนี้)

อินพุต

  • จำนวนเต็มสองจำนวนที่ไม่เป็นลบน้อยกว่า 10 ** 10 (10,000 ล้าน)

เอาท์พุต

  • จำนวนเต็มทั้งหมดที่น้อยกว่า 10 ** 10 และตรงตามเกณฑ์ในส่วนความท้าทาย
  • เป็นที่ยอมรับได้สำหรับเอาต์พุตหลักที่มากกว่า 10 ** 10 แต่ไม่เป็นข้อกำหนด
  • เนื่องจากตัวเลขที่ซ้ำกันเป็นไปตามรูปแบบ (เช่น777) เป็นไปได้ว่ามีจำนวนอนันต์ที่ตรงกับเกณฑ์ แต่โปรแกรมของคุณไม่จำเป็นต้องส่งออกไปตลอดกาล
  • หากไม่มีจำนวนเต็มเช่นนี้ให้เอาท์พุทสิ่งที่คุณต้องการตราบใดที่มันไม่ใช่ตัวเลข (ไม่มีอะไรว่างเปล่าอาเรย์ที่ว่างเปล่าข้อความแสดงข้อผิดพลาดหน้าเศร้า ฯลฯ )
  • หากตัวเลขที่ตรงกับรูปแบบปรากฏขึ้นมากกว่าหนึ่งครั้งในลำดับคุณสามารถส่งออกครั้งเดียวหรือหลายครั้งตามที่เกิดขึ้น
  • หากอินพุตใด ๆ ตรงตามเกณฑ์ก็ควรรวมอยู่ในเอาต์พุต

กฎระเบียบ

ตัวอย่าง / กรณีทดสอบ

Input , Output   
[1,10] , []   

[0,1] , [987]   
[2,1] , [123]   
[2,3] , [987]   

[61,86] , [147]   
[75,90] , [420]   
[34,74] , [1234]   
[59,81] , [2468]   
[84,85] , [7531]   

[19,46] , [111]   
[60,81] , [222]   
[41,42] , [333]   
[13,81] , [444]   
[31,50] , [555]   
[15,42] , [666]   
[94,99] , [777]   
[72,66] , [888]  
[3189,826] , [888888888]    

[15,3] , [159,258]   
[22,51] , [321,1357]   
[74,85] , [159,4444]   
[27,31] , [147,11111]   

[123,0] , [123,123,123,246,369]   
[111,0] , [111,111,111,222,333,555,888]
[111,222] , [111,222,333,555,888]      

[33345,692] , [987654321]   
[3894621507,5981921703] , [9876543210]
[765432099,111111111] , [111111111,876543210,987654321]   

[1976,123] , [123, 2222, 4321, 6543, 45678]   

1
กรณีทดสอบที่แนะนำ: [1976, 123] -> [123, 2222, 4321, 6543, 45678], [3189, 826] -> [888888888],[33345, 692] -> [987654321]
Arnauld

@Arnauld เยี่ยมมาก! ฉันสงสัยว่าคู่เริ่มต้นตัวใดที่มีค่าเอาต์พุตส่วนใหญ่น้อยกว่า 10B อะไรก็ตามข้างต้นที่จะ repdigits และที่น่าเบื่อ
Engineer Toast

@ Arnauld ขอบคุณสำหรับการแก้ไขกรณีทดสอบ ในตัวกำเนิดดั้งเดิมของฉันฉันไม่ได้รวมอินพุต ฉันคิดถึงสองคนนี้อย่างชัดเจนเมื่อฉันกลับไปและเพิ่มพวกเขา
Engineer Toast

คำตอบ:


9

MATL , 14 ไบต์

ขอบคุณ Emigna ที่ชี้ให้เห็นข้อผิดพลาดตอนนี้ได้รับการแก้ไข

`yVdd~?yD]wy+T

วงวนไม่สิ้นสุดที่แสดงผลลัพธ์ตามที่พบ

ลองออนไลน์! โปรดทราบว่าในล่ามออนไลน์ผลลัพธ์จะปรากฏขึ้นหลังจากหมดเวลา 1 นาที

คำอธิบาย

อนุญาตF(n)และF(n+1)แสดงถึงคำทั่วไปสองลำดับติดต่อกันของลำดับฟีโบนักชี ทวนของวงแต่ละคนเริ่มด้วยสแต็คที่มีF(n), สำหรับบางคนF(n+1)n

`         % Do...while
  y       %   Duplicate from below. Takes the two inputs F(0), F(1) (implicitly)
          %   in the first iteration
          %   STACK: F(n), F(n+1), F(n)
  V       %   Convert to string. Let the digits of F(n) be '3579' for example
          %   STACK: F(n), F(n+1), '3579'
  d       %   Consecutive differences (of ASCII codes)
          %   STACK: F(n), F(n+1), [2 2 2]
  d       %   Consecutive differences
          %   STACK: F(n), F(n+1),  [0 0]
  ~       %   Logical negate, element-wise
          %   STACK: F(n), F(n+1), [1 1]
  ?       %   If top of the stack is non-empty and only contains non-zero entries
          %   (this is the case for digits '3579', but not for '3578' or '33')
          %   STACK: F(n), F(n+1)
    y     %     Duplicate from below
          %     STACK: F(n), F(n+1), F(n)
    D     %     Display immediately. This prints the copy of F(n)
          %     STACK: F(n), F(n+1)
  ]       %   End
  w       %   Swap
          %   STACK: F(n+1), F(n)
  y       %   Duplicate from below
          %   STACK: F(n+1), F(n), F(n+1)
  +       %   Add. Note that F(n)+F(n+1) is F(n+2) 
          %   STACK: F(n+1), F(n+2)
  T       %   Push true. This will be used as loop condition
          %   STACK: F(n+1), F(n+2), true
          % End (implicit). The top of the stack is consumed as loop condition.
          % Since it is true, a new iteration will begin, with the stack
          % containing F(n+1), F(n+2)

6

05AB1E , 17 16 15 ไบต์

тFÂ2£O¸«}ʒS¥¥_W

ลองออนไลน์!

คำอธิบาย

                  # implicitly input list of F(0) and F(1)
тF      }         # 100 times do:
  Â               # bifurcate current list
   2£             # take the first 2 items
     O            # sum
      ¸«          # append to list
         ʒ        # filter, keep only elements that are true after:
          S¥¥     # delta's of delta's of digits
             _    # logically negate each
              W   # min

5

JavaScript (ES6), 85 84 81 ไบต์

f=(p,q,a=[])=>p|q?f(q,p+q,![...p+''].some(x=d=n=>r=d-(d=x-(x=n)))/r?[...a,p]:a):a

ลองออนไลน์!

ทดสอบตัวเลขที่อยู่ติดกัน

![...p + ''].some(x = d = n => r = d - (d = x - (x = n))) / r

ทั้งxและdจะเริ่มต้นทำงานในฟังก์ชั่นที่ไม่ระบุชื่อซึ่งกองกำลังNaNสำหรับการดำเนินการทางคณิตศาสตร์ทั้งหมดที่พวกเขามีส่วนร่วมใน. ย้ำแรกของsome()เสมอให้(d = [function] - n) === NaNและ(r = [function] - d) === NaN(falsy) ในการทำซ้ำครั้งที่สองเรามีd = x - n(จำนวนเต็ม) และ(r = NaN - d) === NaN(เท็จอีกครั้ง) เริ่มต้นจากการทำซ้ำครั้งที่สามrถูกตั้งค่าเป็นจำนวนเต็มซึ่งไม่ใช่ศูนย์หากความแตกต่างระหว่างตัวเลข # 3 และตัวเลข # 2 ไม่เท่ากับความแตกต่างระหว่างตัวเลข # 2 และตัวเลข # 1

ตัวเลขpเป็นไปตามเกณฑ์ที่กำหนดหากและหากsome()เป็นเท็จ (ตัวเลขที่อยู่ติดกันทั้งหมดมีความแตกต่างกัน) และค่าสุดท้ายของrคือ0 (มีการวนซ้ำอย่างน้อย 3 ครั้ง) สิ่งนี้ให้!false / 0 === true / 0 === Infinity(ความจริง)

เราอาจมี:

  • !true / rด้วยr> 0หรือr <0ซึ่งให้false / r === 0(เท็จ)
  • !false / NaNซึ่งให้true / NaN === NaN(เท็จ)

สภาพหยุดพัก

เรียกซ้ำตัวเองหยุดเมื่อp | qประเมิน0 สิ่งนี้รับประกันได้ว่าจะเกิดขึ้นเมื่อทั้งpและqเข้าถึงค่าประมาณ10 25ซึ่งมีความยาว 84 บิต เนื่องจาก JS มี mantissa 52 บิตดังนั้น 32 บิตสุดท้ายจึงเป็นศูนย์ ดังนั้น 32 บิตบิตหรือประเมิน0

เนื่องจากอัตราการเติบโตอย่างรวดเร็วของลำดับนี้เกิดขึ้นค่อนข้างรวดเร็ว


4

Java 8, 151 144 140 136 130 ไบต์

(a,b)->{for(long n,m,d,p;;System.out.print(m>99&p==d?m+" ":""),m=a+b,a=b,b=m)for(m=n=a,d=p=10;n>9&d==p|p>9;d=n%10-(n/=10)%10)p=d;}

วนรอบไม่สิ้นสุดแสดงตัวเลขเมื่อพบ
ลองออนไลน์ (หมดเวลาหลังจาก 60 วินาที)

รุ่น136 ไบต์พร้อมขีด จำกัด10 10 ( a<1e10):

(a,b)->{for(long n,m,d,p;a<1e10;System.out.print(m>99&p==d?m+" ":""),m=a+b,a=b,b=m)for(m=n=a,d=p=10;n>9&d==p|p>9;d=n%10-(n/=10)%10)p=d;}

ลองออนไลน์

คำอธิบาย:

(a,b)->{         // Method with two long parameters and no return-type
  for(long n,m,  //  Temp numbers
           d,p;  //  Current and previous differences
      a<1e10;    //  Loop as long as `a` is still below 10^10
      ;          //    After every iteration:
       System.out.print(
                 //     Print:
        m>99     //      If the number has at least three digits,
        &p==d?   //      and the previous and current differences are still the same
         m+" "   //       Print the current number with a space delimiter
        :        //      Else:
         ""),    //       Print nothing
                 //     Go to the next Fibonacci iteration by:
       m=a+b,    //      Setting the temp-number `m` to `a+b`
       a=b,      //      Replacing `a` with `b`
       b=m)      //      And then setting `b` to the temp number `m`
    for(m=n=a,   //   Set both `m` and `n` to `a`
        d=p=10;  //   Set both `d` and `p` to 10
        n>9      //   Inner loop as long as `n` has at least two digits,
        &d==p    //   and `p` and `d` are still the same,
         |p>9    //   or `p` is still 10
        ;        //     After every iteration:
         d=n%10-(n/=10)%10)
                 //      Set `d` to the difference between the last two digits of `n`
                 //      And integer-divide `n` by 10 at the same time
      p=d;}      //    Set the previous difference `p` to `d`

4

เยลลี่ , 20 19 18 ไบต์

>ȷ2ȧDIEƊ
+ƝḢ;Ɗȷ¡ÇƇ

ลองออนไลน์!

+ƝḢ;Ɗȷ¡สร้างคำหนึ่งพัน ( ȷ) แรกในชุดซึ่งจะเพียงพอเสมอ ฉันคิดว่าอาจเป็นวิธีที่สั้นกว่าในการทำเช่นนี้ +ȷ¡เข้ามาใกล้ แต่จะได้ผลก็ต่อเมื่อเทอมแรกเป็นศูนย์

DIEฉันสมมติว่าเราสามารถใช้ในตัวเลขสองในสิ่งที่ตรงกันข้ามซึ่งจะทำให้หนึ่งไบต์

หากเราไม่จำเป็นต้องใช้สัญญาณขาเข้าอย่างใดอย่างหนึ่ง:

เยลลี่ 15 ไบต์

>ȷ2ȧDIEƊ
+ṄÇ¡ß@

ลองออนไลน์!


5
ความคิดของเรากับทุกไบต์ที่ไม่เกรงกลัวนั้นDIEƊในระหว่างกระบวนการตีกอล์ฟ
Arnauld

4

อ็อกเทฟ , 91 90 83 ไบต์

บันทึกแล้ว 7 ไบต์ขอบคุณ Luis Mendo!

@(t)eval"for i=3:99,if~diff(diff(+num2str(t(1))))disp(t(1))end,t=[t(2) sum(t)];end"

ลองออนไลน์!

มันใช้งานได้ดี!

evalด้วย for loop insideเพื่อบันทึกสองสามไบต์ การข้ามเครื่องหมายทวิภาคและเครื่องหมายอัฒภาคเพื่อบันทึก ใช้ความจริงที่ว่าเวกเตอร์ถือว่า truthy IFF องค์ประกอบทั้งหมดที่มีไม่ใช่ศูนย์ที่จะบันทึกหรือanyall

นอกเหนือจากนั้นมันเป็นการนำ Fibonacci ไปใช้งานจริง



2

Haskell , 105 ไบต์

u%v|let s=u:scanl(+)v s=[n|n<-s,d<-[f(-).map fromEnum.show$n],length d>1,and$f(==)d]
f g=zipWith g=<<tail

กำหนดโอเปอเรเตอร์(%)ที่ส่งคืนรายการอนันต์พร้อมโซลูชันทั้งหมด หากต้องการดูผลลัพธ์จากstdoutเราจำเป็นต้องปิดการใช้งานบัฟเฟอร์ (หรือเรียกใช้ในghciหรือด้วยrunhaskell) ลองออนไลน์!

คำอธิบาย / Ungolfed

ฟังก์ชั่นfเป็นเพียงฟังก์ชั่นผู้ช่วยที่คาดว่าจะมีฟังก์ชั่นไบนารีและรายการมันใช้ฟังก์ชั่นgกับคู่ที่อยู่ติดกันทั้งหมด เป็นหลักเหมือนกับ:

adjacent g xs = zipWith (tail xs) xs

โอเปอเรเตอร์(%)เป็นเพียงความเข้าใจในรายการที่ใช้ตัวกรองบางอย่าง (ตรวจสอบให้แน่ใจว่ามีอย่างน้อย 3 หลัก & ว่าตัวเลขที่อยู่ติดกันนั้นมีระยะทางเท่ากัน):

u % v
  -- recursively define s as the "Fibonacci sequence" with f(0) = u and f(1) = v
  | let sequence = u : scanl (+) v sequence
  -- take all numbers from that sequence using the filters below
  = [ number | number <- sequence
  -- convert to string, get the ASCII codepoints and build a list of the adjacent differences
        , let differences = adjacent (-) . map fromEnum . show $ number
  -- numbers with > 3 digits have >= 2 adjacent digits (or rather differences of digits)
        , length differences > 1
  -- make sure all of these are equal by comparing them and reducing with logical and
        , and $ adjacent (==) differences
    ]

2

CJam , 55 ไบต์

q~{1$_99>"_`2\ew{{-}*}%""3,"?~_(+="0$p"*~;_@+_11_#<}g;;

ลองออนไลน์!

การส่ง CJam ครั้งแรกของฉันไม่สั้นมาก แต่สนุกมาก ข้อเสนอแนะใด ๆ ยินดีต้อนรับ!


ขอบคุณมากสำหรับเคล็ดลับ! ฉันได้อัปเดตการส่ง
maxb

2

Stax , 26 24 ไบต์

Ç╕SôεPN^:·░ßⁿ {@ÿ}Ü╫╣1╣X

เรียกใช้และแก้ไขข้อบกพร่อง

คำอธิบาย

E{b+}99*L{E%2>|cd_E:-u%1=!C_Qf    # Full program, unpacked, implicit input
E                                 # Push all elements from array onto stack.
 {b+}99*L                         # Generate the first 99 numbers of the  Fibonacci sequence given the input
         {                   f    # Loop through all Fibonacci elements
          E                       # Array of decimal digit
           %2>                    # Does the array have at least 3 digits
              |c                  # Assume Truthy past this point
                d                 # discard top of stack
                 _E               # Copy the current element of the Fibonacci sequence and Digitize it
                  :-              # Pairwise difference of array.
                    :u            # Is there exactly 1 unique number
                        !C        # Flip the comparison, if truthy proceed
                          _Q      # Copy the current element of the Fibonacci sequence and Peek and print with a newline.

ไม่สั้นอย่างที่ฉันต้องการและอาจจะเล่นกอล์ฟได้มากกว่านี้ แต่ใช้งานได้



1

จูเลีย 0.6 , 86 81 bytes

a<b=b>=0&&((n->n>99&&2>endof(∪(diff(digits(n))))&&println(n)).([a,b]);a+b<a+2b)

ลองออนไลน์!

ค่อนข้างตรงไปตรงมา - ตรวจสอบว่าอินพุตมีตัวเลขอย่างน้อย 3 หลัก ( n>99) จากนั้นรับความแตกต่างระหว่างแต่ละคู่หลักในตัวเลข (diff(digits(n)) ) ตรวจสอบว่าความยาวของ ( endof) ชุดที่ไม่ซ้ำกันของ ( ) แตกต่างเหล่านั้นคือ 1 (เช่น เหมือนกัน) และหากเป็นเช่นนั้นให้พิมพ์หมายเลข ทำเช่นนั้นสำหรับทั้งสองหมายเลขที่กำหนดจากนั้นเรียกใช้ฟังก์ชันซ้ำด้วยหมายเลขสองถัดไป

(น่าเสียดายที่ดูเหมือนว่าจะ±มีลำดับความสำคัญสูงกว่า+มิฉะนั้นอาจมีการโทรครั้งสุดท้ายa+b±a+2bประหยัดได้ 3 ไบต์)ตอนนี้โอเวอร์โหลดตัว<ดำเนินการมากเกินไปซึ่งจะช่วยประหยัดทั้งตัวดำเนินการไบต์และวงเล็บที่สำคัญกว่า (ไม่สามารถใช้<ในรหัสของเราแม้ว่าดังนั้นเพียงแค่การปรับปรุงใหม่endof(...)<2เพื่อ2>endof(...))

หากมีการส่งออกภายนอกที่ได้รับอนุญาตเราสามารถบันทึก 2 ไบต์ใช้@showแทนการprintlnพิมพ์แทนเพียงn = 987 987เรายังสามารถใช้dumpเวลา 1 ไบต์ต่ำกว่านั้น แต่dumpพิมพ์ข้อมูลชนิดพร้อมกับค่าเพื่อส่งออกจะแทนเพียงInt64 987987

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