Đếm các quỹ đạo Fibonacci


13

Nếu chúng ta định nghĩa một chuỗi giống như Fibonacci là f k (n) = (f k (n-1) + f k (n-2))% k , đối với một số nguyên k (trong đó % là toán tử modulo), chuỗi sẽ nhất thiết phải theo chu kỳ, vì chỉ có k 2 giá trị khác nhau cho (f k (n-1), f k (n-2)) . Tuy nhiên, chu trình này thường không bao gồm tất cả các cặp giá trị có thể, do đó tùy thuộc vào hai giá trị bắt đầu f k (0)f k (1) , chúng ta có thể có các chu kỳ khác nhau. Ví dụ: với k = 2, chúng tôi có bốn khả năng sau, tùy thuộc vào hai giá trị đầu tiên:

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, ...

Do tính chất tuần hoàn của các trình tự, thực sự chỉ có hai trình tự khác nhau cơ bản ở đây, với quỹ đạo (0)(0, 1, 1) . Hãy xem 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, ...

Một lần nữa, chỉ có hai quỹ đạo khác nhau: (0)(0, 1, 1, 2, 0, 2, 2, 1) .

Đối với k cao hơn, chúng ta có thể nhận được nhiều quỹ đạo hơn, nhưng chúng vẫn sẽ rơi vào một số lượng nhỏ các lớp tương đối. Ví dụ k = 4 mang lại bốn quỹ đạo (0) , (0,1,1,2,3,1) , (0, 2, 2) , (0, 3, 3, 2, 1, 3)k = 5 ba quỹ đạo (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) .

Nhiệm vụ của bạn trong thử thách này là tính toán số lượng quỹ đạo mà chuỗi tạo ra cho một k cho trước . Đây là OEIS A015134 . Dưới đây là 100 giá trị đầu tiên (bắt đầu từ 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

Đảm bảo kiểm tra k = 11 , đây là đầu vào đầu tiên mang lại nhiều hơn k quỹ đạo.

Quy tắc

Bạn được cung cấp một số nguyên dương k và sẽ xuất A015134 (k) .

Bạn có thể viết một chương trình hoặc một chức năng và sử dụng bất kỳ phương pháp tiêu chuẩn nào để nhận đầu vào và cung cấp đầu ra.

Bạn có thể sử dụng bất kỳ ngôn ngữ lập trình nào , nhưng lưu ý rằng các lỗ hổng này bị cấm theo mặc định.

Đây là , vì vậy câu trả lời hợp lệ ngắn nhất - được đo bằng byte - thắng.


3
Điều này đủ gần với codegolf.stackexchange.com/q/26578/194 mà tôi sẽ không đơn phương đóng nó nhưng tôi sẽ bỏ phiếu thứ 5 để đóng dưới dạng dupe.
Peter Taylor

Câu trả lời:


3

Husk , 17 16 byte

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

Hãy thử trực tuyến!

Giải trình

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

Ngôn ngữ Wolfram (Mathicala) , 76 70 byte

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

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

Chúng tôi xây dựng biểu đồ được đưa ra bởi các quy tắc {{0,0}->{0,0}, {1,0}->{1,1}, ...}, đưa ra hai yếu tố của chuỗi Fibonacci tổng quát, tìm một mô đun tiếp theo n. Việc EdgeCycleMatrixđưa ra ma trận tỷ lệ từ chu kỳ đến các cạnh trong biểu đồ này; chúng tôi muốn đếm hàng của nó.

(Có một số tích hợp thực hiện một nhiệm vụ tương tự, nhưng ConnectedComponentsdài hơn và FindCyclecần nhiều đầu vào bổ sung để làm cho nó hoạt động. Bên cạnh đó, EdgeCycleMatrixlà một mảng hình chữ nhật, không có hình dạng ngộ nghĩnh như hai cái kia, giúp sau này. )

Để đếm các hàng của ma trận, chúng ta lấy giai thừa của các mục để biến nó thành ma trận của tất cả các mục, sau đó lấy dấu vết. (Mỗi chu kỳ chứa ít nhất một cạnh và do đó có ít nhất nhiều cột như các hàng - vì vậy, điều này sẽ tính các hàng chứ không phải các cột.)


1

MATL , 38 36 byte

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

Hãy thử trực tuyến! Nó lần ra trong trình biên dịch trực tuyến cho đầu vào vượt quá7.

Giải trình

Mã xác định quỹ đạo theo các số phức, trong đó phần ảo là thuật ngữ mới và phần thực là thuật ngữ trước trong chuỗi Fibonacci. Mỗi giá trị phức tạp mã hóa trạng thái của chuỗi. Cụ thể, đưa ra a+jbgiá trị tiếp theo được tính là b+j(a+b).

Các giá trị bắt đầu có thể là a+jbvới a, btrong [0, 1, ..., k-1]. Đối với mỗi giá trị bắt đầu, mã lặp lại k^2lần. Trên thực tế, để làm cho mã ngắn hơn, mỗi lần lặp được áp dụng cho tất cả các giá trị được tích lũy cho đến nay và kết quả được lặp lại (dù sao cuối cùng cũng sẽ cần thiết). Sau lần lặp cuối cùng, vectơ của các giá trị phức được lặp lại được sắp xếp (theo giá trị tuyệt đối, sau đó theo góc). Điều này cung cấp một "chữ ký" cho mỗi quỹ đạo.

Vào cuối chương trình, chữ ký được thu thập vào một mảng ô. Số lượng chữ ký duy nhất là đầu ra mong muốn.

: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 byte

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

Hãy thử trực tuyến!

Điều này có lẽ có thể được cải thiện. Đặc biệt nếu ai đó có thể tìm cách tránh isInfixOfvà loại bỏ việc nhập.

Ý tưởng cơ bản là tạo ra một danh sách "trạng thái" (bộ chứa hai giá trị trước đó) để xem khi nào nó bắt đầu chu kỳ. Sau đó, chúng tôi kiểm tra xem mỗi quỹ đạo có khác với các tiền thân của nó hay không (thực sự hoạt động theo cách khác nhưng thật khó để diễn tả thành lời). Để kiểm tra xem các quỹ đạo có giống nhau hay không, chúng tôi kiểm tra xem độ dài có giống nhau không và liệu một cái có khớp với cái kia được nối với chính nó không. Ví dụ [0,2,2], [2,2,0]: chiều dài của cả hai là 3 và [0,2,2,0,2,2]chứa [2,2,0]như một dãy liên tục. Tôi không chắc chắn nếu nó hoàn hảo nhưng nó dường như hoạt động.

EDIT: cảm ơn Laikoni vì đã gỡ 5 byte! Tôi nên đọc thêm những lời khuyên đó.


1
Có vẻ như bạn có thể sử dụng mẹo này để tránh length. Byte khác có thể được lưu trong !với |r<-p++[a]=r!b.
Laikoni

0

JavaScript (ES6), 337 335 byte

Xin lỗi cho thuật toán brute-force Ω (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}

Hiệu suất ... Khi tôi tính A015134 (một cái gì đó vượt quá k = 50), nó vượt quá giới hạn 60 giây trên 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)}`);

Giải thích (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 byte

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

Trả về một hàm trả về kết quả. Để có thêm 3 byte, chúng ta có thể trả về kết quả trực tiếp:

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)

Cả hai đều có độ phức tạp thời gian O (n 2 ).


0

Python 2 , 214 byte

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)

Hãy thử trực tuyến!

Nó không hiệu quả lắm nhưng nó là thứ tốt nhất tôi có thể làm.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.