การนับ Fibonacci Orbits


13

หากเรากำหนดลำดับ Fibonacci-like เป็นf k (n) = (f k (n-1) + f k (n-2))% k , สำหรับจำนวนเต็มkจำนวนหนึ่ง(โดยที่%คือตัวดำเนินการโมดูโล), ลำดับ จำเป็นจะต้องเป็นวงกลมเพราะมีเพียงk 2ค่าที่แตกต่างกันสำหรับ(ฉk (n-1), F k (n-2)) อย่างไรก็ตามรอบนี้มักจะไม่รวมค่าที่เป็นไปได้ทั้งหมดดังนั้นขึ้นอยู่กับค่าเริ่มต้นสองค่าf k (0)และf k (1)เราอาจได้รับรอบที่แตกต่างกัน ตัวอย่างเช่นสำหรับk = 2เรามีความเป็นไปได้สี่อย่างดังต่อไปนี้ขึ้นอยู่กับค่าสองค่าแรก:

0, 0, 0, 0, 0, 0, 0, 0, 0, ...
0, 1, 1, 0, 1, 1, 0, 1, 1, ...
1, 0, 1, 1, 0, 1, 1, 0, 1, ...
1, 1, 0, 1, 1, 0, 1, 1, 0, ...

เนื่องจากวงจรธรรมชาติของลำดับที่มีจริงๆเพียงสองลำดับที่แตกต่างกันที่นี่มีวงโคจร(0)และ(0, 1, 1) ลองดูk = 3 :

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
0, 1, 1, 2, 0, 2, 2, 1, 0, 1, 1, 2, 0, 2, 2, 1, ...
0, 2, 2, 1, 0, 1, 1, 2, 0, 2, 2, 1, 0, 1, 1, 2, ...
1, 0, 1, 1, 2, 0, 2, 2, 1, 0, 1, 1, 2, 0, 2, 2, ...
1, 1, 2, 0, 2, 2, 1, 0, 1, 1, 2, 0, 2, 2, 1, 0, ...
1, 2, 0, 2, 2, 1, 0, 1, 1, 2, 0, 2, 2, 1, 0, 1, ...
2, 0, 2, 2, 1, 0, 1, 1, 2, 0, 2, 2, 1, 0, 1, 1, ...
2, 1, 0, 1, 1, 2, 0, 2, 2, 1, 0, 1, 1, 2, 0, 2, ...
2, 2, 1, 0, 1, 1, 2, 0, 2, 2, 1, 0, 1, 1, 2, 0, ...

อีกครั้งมีเพียงสองวงโคจรที่แตกต่างกัน: (0)และ(0, 1, 1, 2, 0, 2, 2, 1)

สำหรับk ที่สูงกว่าเราอาจได้รับวงโคจรมากขึ้น แต่พวกมันจะยังคงอยู่ในชั้นเรียนที่มีจำนวนน้อย ตัวอย่างเช่นk = 4ให้ผลสี่วงโคจร(0) , (0,1,1,2,3,1) , (0, 2, 2) , (0, 3, 3, 2, 1, 3)และk = 5วงโคจรทั้งสาม(0) , (0, 1, 1, 2, 3, 0, 3, 3, 1, 4, 0, 4, 4, 3, 2, 0, 2, 2, 4, 1)และ(1, 3, 4, 2)

งานของคุณในการท้าทายนี้คือการคำนวณว่าวงโคจรเรียงตามลำดับสร้างกี่k นี่คือOEIS A015134 นี่คือ 100 ค่าแรก (เริ่มต้นจากk = 1 ):

1, 2, 2, 4, 3, 4, 4, 8, 5, 6, 14, 10, 7, 8, 12, 16, 9, 16, 22, 16,
29, 28, 12, 30, 13, 14, 14, 22, 63, 24, 34, 32, 39, 34, 30, 58, 19,
86, 32, 52, 43, 58, 22, 78, 39, 46, 70, 102, 25, 26, 42, 40, 27, 52,
160, 74, 63, 126, 62, 70, 63, 134, 104, 64, 57, 78, 34, 132, 101, 60,
74, 222, 37, 38, 62, 328, 89, 64, 82, 124, 41, 86, 42, 172, 75, 44,
184, 178, 181, 132, 82, 180, 99, 140, 104, 246, 49, 50, 114, 76

ตรวจสอบให้แน่ใจเพื่อตรวจสอบk = 11ซึ่งเป็นอินพุตแรกที่ให้ผลมากกว่าk orbits

กฎระเบียบ

คุณได้รับเป็นจำนวนเต็มบวกkและควรเอาท์พุทA015134 (k)

คุณสามารถเขียนโปรแกรมหรือฟังก์ชั่นและใช้วิธีการมาตรฐานใด ๆ ในการรับอินพุตและจัดเตรียมเอาต์พุต

คุณอาจใช้ภาษาการเขียนโปรแกรมใด ๆแต่โปรดทราบว่าช่องโหว่เหล่านี้ถูกห้ามใช้โดยปริยาย

นี่คือดังนั้นคำตอบที่สั้นที่สุดที่ถูกต้อง - วัดเป็นไบต์ - ชนะ


3
นี่อยู่ใกล้พอที่จะcodegolf.stackexchange.com/q/26578/194ว่าฉันจะไม่ปิดมันเพียงฝ่ายเดียว แต่ฉันจะลงคะแนนครั้งที่ 5 ให้ปิดเพื่อล่อลวง
Peter Taylor

คำตอบ:


3

Husk , 17 16 ไบต์

Lüȯ€U¡ȯ↔m%⁰∫π2ŀ⁰

ลองออนไลน์!

คำอธิบาย

Lüȯ€U¡ȯ↔m%⁰∫π2ŀ⁰  Implicit input, say n=4.
              ŀ⁰  Lowered range: [0,1,2,3]
            π2    Cartesian second power: [[0,0],[0,1],[1,0],[0,2]..
 üȯ                Deduplicate with respect to this function:
   €U¡ȯ↔m%⁰∫       Arguments are two pairs, say a=[0,2], b=[1,1]
     ¡ȯ            Iterate on a:
           ∫       Cumulative sum,
        m%⁰        take modulo n of each,
       ↔           then reverse: [[0,2],[2,0],[2,2],[0,2],[2,0]..
    U              Cut at first repeated element: [[0,2],[2,0],[2,2]]
   €               Is b in this list? No, so they are distinct in ü.
L                 Number of remaining pairs.


1

ภาษา Wolfram (Mathematica) , 76 70 ไบต์

Tr[EdgeCycleMatrix[#->{#[[2]],Tr@#~Mod~n}&/@Tuples[Range[n=#]-1,2]]!]&

ลองออนไลน์!

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

เราสร้างกราฟที่กำหนดโดยกฎว่าได้รับสององค์ประกอบของลำดับฟีโบนักชีทั่วไปพบว่าหนึ่งต่อไปแบบโมดูโล{{0,0}->{0,0}, {1,0}->{1,1}, ...} nThe EdgeCycleMatrixให้เมทริกซ์อุบัติการณ์จากวงจรถึงขอบในกราฟนี้ เราต้องการนับแถวของมัน

(มีบิวด์อินจำนวนมากที่ทำงานคล้ายกัน แต่ConnectedComponentsมีความยาวและFindCycleต้องการอินพุตเพิ่มเติมจำนวนมากเพื่อให้สามารถใช้งานได้นอกจากนี้ยังEdgeCycleMatrixมีอาร์เรย์สี่เหลี่ยมไม่ใช่รูปตลกที่คล้ายกับอีกสองอันซึ่งจะช่วยในภายหลัง )

ในการนับแถวของเมทริกซ์เราใช้แฟคทอเรียลของรายการเพื่อเปลี่ยนมันเป็นเมทริกซ์ของทุกคนจากนั้นทำการติดตาม (แต่ละวงรอบมีอย่างน้อยหนึ่งขอบและดังนั้นจึงมีอย่างน้อยคอลัมน์มากเท่าแถว - ดังนั้นนี่จะนับจำนวนแถวและไม่ใช่คอลัมน์)


1

MATL , 38 36 ไบต์

:qt!J*+le"@GU:"t&Zjwy+G\J*+hu]S]Xhun

ลองออนไลน์! 7มันหมดเวลาในคอมไพเลอร์ออนไลน์สำหรับการป้อนข้อมูลเกิน

คำอธิบาย

รหัสกำหนดวงโคจรในแง่ของจำนวนเชิงซ้อนที่ส่วนจินตภาพเป็นคำใหม่และส่วนที่แท้จริงคือคำก่อนหน้าในลำดับฟีโบนักชี แต่ละค่าที่ซับซ้อนเข้ารหัสสถานะของลำดับ กล่าวคือได้รับความคุ้มค่าต่อไปคือการคำนวณa+jbb+j(a+b)

ค่าเริ่มต้นเป็นไปได้a+jbด้วยa, ในb [0, 1, ..., k-1]สำหรับแต่ละค่าเริ่มต้นรหัส iterates k^2ครั้ง ที่จริงแล้วเพื่อทำให้รหัสสั้นลงการวนซ้ำแต่ละครั้งจะถูกนำไปใช้กับค่าที่สะสมไว้ทั้งหมดเพื่อให้ได้ผลลัพธ์และขจัดความซ้ำซ้อน (ซึ่งเป็นสิ่งที่จำเป็นในตอนท้าย) หลังจากการวนซ้ำครั้งล่าสุดเวกเตอร์ของค่าเชิงซ้อนที่ซ้ำซ้อนจะถูกจัดเรียง (ตามค่าสัมบูรณ์แล้วตามด้วยมุม) สิ่งนี้จะให้ "ลายเซ็น" สำหรับแต่ละวงโคจร

ในตอนท้ายของโปรแกรมลายเซ็นจะถูกรวบรวมไว้ในอาร์เรย์เซลล์ จำนวนลายเซ็นที่ไม่ซ้ำกันคือผลลัพธ์ที่ต้องการ

:q          % Implicit input: k. Push row vector [0, 1, ..., k-1]
t!          % Duplicate, transpose: gives column vector [0; 1; ...; k-1]
J*+         % Multiply by 1j, add with broadcast. Gives a k × k matrix of
            % values a+jb with a, b in [0, 1, ..., k-1]
le          % Linearize into a row vector
"           % For each c in that vector
  @         %   Push c
  GU:"      %   Do the following k^2 times
    t&Zj    %     Duplicate and split into real and imaginary parts: a, b
    wy+     %     Swap, duplicate, from below, add: transforms a, b into
            %     b, a+b. This is the basic step in the Fibonacci sequence
            %     In subsequent iterations a and b may be vectors instead
            %     of numbers, as they include all values obtained so far
    G\      %     Modulo k, element-wise
    J*+     %     Times 1j, add. Gives the next complex number for each of
            %     the complex numbers so far
    hu      %     Append to values so far and deduplicate. This may extend
            %     the vector of complex numbers
  ]         %   End
  S         %   Sort
]           % End
Xh          % Collect entire stack into a cell array
u           % Deduplicate
n           % Number of entries. Implicit display

1

Haskell , 196 191 ไบต์

import Data.List
o(a:b)=1+o[x|x<-b,not$(0<$a)==(0<$x)&&isInfixOf a(x++x)]
o _=0
k#(a,b)=(b,mod(a+b)k)
p!(a:b)|elem a p=fst<$>p|r<-p++[a]=r!b
f k=o[[]!iterate(k#)(a,b)|a<-[0..k-1],b<-[0..k-1]]

ลองออนไลน์!

สิ่งนี้อาจปรับปรุงได้ โดยเฉพาะอย่างยิ่งถ้าใครบางคนสามารถหาวิธีที่จะหลีกเลี่ยงisInfixOfและลบการนำเข้า

แนวคิดพื้นฐานคือการสร้างรายการ "สถานะ" (tuples ที่มีค่าก่อนหน้านี้สองค่า) เพื่อดูว่าเมื่อใดที่จะเริ่มรอบ จากนั้นเราตรวจสอบว่าแต่ละวงโคจรนั้นแตกต่างจากรุ่นก่อนหรือไม่ ในการตรวจสอบว่าวงโคจรนั้นเหมือนกันหรือไม่เราจะตรวจสอบว่าความยาวนั้นเหมือนกันหรือไม่และเรามีความสอดคล้องกับส่วนอื่นหรือไม่ ตัวอย่างเช่น[0,2,2], [2,2,0]: ความยาวของทั้งสองคือ 3 และ[0,2,2,0,2,2]มี[2,2,0]เป็น subsequence อย่างต่อเนื่อง ฉันไม่แน่ใจว่ามันจะเข้าใจผิด แต่ดูเหมือนว่าจะทำงาน

แก้ไข: ขอบคุณ Laikoni สำหรับการปิด 5 ไบต์! ฉันควรอ่านเคล็ดลับเหล่านั้นเพิ่มเติม


1
ดูเหมือนว่าคุณสามารถใช้เคล็ดลับนี้lengthเพื่อหลีกเลี่ยงการ ไบต์อีกจะถูกบันทึกไว้ในที่มี! |r<-p++[a]=r!b
Laikoni

0

JavaScript (ES6), 337 335 ไบต์

ขออภัยสำหรับอัลกอริธึม br (k ^ 3)

(k,x=o=0,u=[],s=(q,w,v,j=d=0)=>{while(j++<v)d|=q.reduce((a,b,i)=>a&=b==w[(i+j)%v],1);return d})=>{for(;x<k;x++)for(y=0;y<k;y++){l=2;r=[x,y];do{r.push((c=(d=r[(l+=2)-3])+r[l-4])%k,(c+d)%k)}while(!(t=r.slice(0,h=l/2)).reduce((a,b,i)=>a&=b==r[i+h],1));if(!u.reduce((q,z)=>q|=(t.length-(a=z.length)?0:s(t,z,a)),0)){o++;u.push(t)}}return o}

ประสิทธิภาพ ... เมื่อฉันคำนวณ A015134 (บางอย่างที่เกิน k = 50) มันเกิน 60 วินาทีใน TIO

var g=(k,x=o=0,u=[],s=(q,w,v,j=d=0)=>{while(j++<v)d|=q.reduce((a,b,i)=>a&=b==w[(i+j)%v],1);return d})=>{for(;x<k;x++)for(y=0;y<k;y++){l=2;r=[x,y];do{r.push((c=(d=r[(l+=2)-3])+r[l-4])%k,(c+d)%k)}while(!(t=r.slice(0,h=l/2)).reduce((a,b,i)=>a&=b==r[i+h],1));if(!u.reduce((q,z)=>q|=(t.length-(a=z.length)?0:s(t,z,a)),0)){o++;u.push(t)}}return o}

for (var ix = 1; ix <= 15; ix++)
 console.log(`A015134(${ix}) = ${g(ix)}`);

คำอธิบาย (Ungolfed)

function CheckIfSameOrbit(Array_1, Array_2, Length) { // Checks if the orbits are equal
  var d = false, j = 0;                               // Assume both have same length
  while (j < v) {                                     // Checks for different startings
    j++;                                                
    d |= Array_1.reduce(function(Acc, Item, Index) {  // Element-by-element comparison
      Acc &= Item == w[(Index + j) % v], 1);                     
    });                                               // Return true if any starting
  }                                                   // point makes two orbits identical
}

function A015134(k) {                                 // Main Program
  var o = 0, u = [];                                    
  for (var x = 0; x < k; x++) {                       // Checks different pairs of (x, y)
    for (var y = 0; y < k; y++) {
      var l = 2, r = [x, y], h = 1, t;
      do {                                            // Find until a complete orbit is
        l += 2;                                       // found (except for (0, 0) case)
        h = l / 2;
        var d = r[l - 3], c = r[l - 3] + r[l - 4];
        r.push(c % k, (c + d) % k);
        t = r.slice(0, h);
      }                                                 
      while (!t.reduce(function(Acc, Item, Index) {   // Which is, if 2 identical copies
        Acc &= Item == r[Index + h];                  // of the orbit are calculated
      }, 1));

      if (!u.reduce(function(Acc, Item) {             // If the orbit is a new one
        var a = Item.length;
        Acc |= (t.length - a ? 0 : s(t, Item, a));
      }, 0)) {
        o++;                                          // Increment the counter, and
        u.push(t);                                    // record it to the list
      }
    }
  }
  return o;                                           // Ultimately return the counter;
}



0

JavaScript (ES6), 102 ไบต์

k=>F=(a=0,b=0,C=0,q)=>q?F[q=[a,b%=k]]?0:1|F(b,a+b,C,F[q]=1):b<k?F(a,b+1,C+F(a,b,C,1)):++a<k?F(a,0,C):C

ส่งคืนฟังก์ชันซึ่งส่งคืนผลลัพธ์ สำหรับ 3 ไบต์เพิ่มเติมเราสามารถให้ผลลัพธ์คืนโดยตรง:

k=>(F=(a,b,C,q)=>q?F[q=[a,b%=k]]?0:1|F(b,a+b,C,F[q]=1):b<k?F(a,b+1,C+F(a,b,C,1)):++a<k?F(a,0,C):C)(0,0,0)

ทั้งสองมีความซับซ้อนของเวลา O (n 2 )


0

Python 2 , 214 ไบต์

def h(k):
 R=[]
 for p in[[i/k,i%k,(i/k+i%k)%k]for i in range(k*k)]:
	while p[:2]!=p[-2:]:
		p.append(sum(p[-2:])%k)
	p=p[:-2]
	if not any([p==x[i:]+x[:i]for i in range(len(p))for x in R]):R.append(p)
 print len(R)

ลองออนไลน์!

มันไม่ได้มีประสิทธิภาพมากนัก แต่มันเป็นกอล์ฟที่ฉันสามารถทำได้

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