피보나치 궤도 계산


13

피보나치 유사 시퀀스를 f k (n) = (f k (n-1) + f k (n-2)) % k로 정의 하면 정수 k (여기서 % 는 모듈로 연산자)에 대해 시퀀스 (f k (n-1), f k (n-2))에 대해 k 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 궤도 이상을 산출하는 첫 번째 입력 인 k = 11 을 확인하십시오 .

규칙

양의 정수 k 가 주어지고 A015134 (k)를 출력해야합니다 .

사용자가 쓸 수 프로그램이나 함수를 상기의 어떠한 사용도 표준 방법 의 입력을 수신하고 출력을 제공한다.

모든 프로그래밍 언어를 사용할 수 있지만 이러한 허점 은 기본적으로 금지되어 있습니다.

이것은 이므로 바이트 단위로 측정 된 가장 짧은 유효한 답변이 이깁니다.


3
이것은 codegolf.stackexchange.com/q/26578/194에 충분히 가까워서 일방적으로 닫지 않을 것이지만 5 번째 투표를해서 속임수로 마감 할 것입니다.
피터 테일러

답변:


3

껍질 , 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 Language (Mathematica) , 76 70 바이트

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

온라인으로 사용해보십시오!

작동 원리

{{0,0}->{0,0}, {1,0}->{1,1}, ...}일반화 된 피보나치 수열의 두 가지 요소가 주어지면 다음 모듈로를 찾는 규칙에 의해 주어진 그래프를 구성합니다 n. 은 EdgeCycleMatrix이 그래프에서 에지까지주기에서 접속 행렬을 준다; 행을 세고 싶습니다.

(유사한 작업을 수행하는 ConnectedComponentsFindCycle많은 내장 기능이 있지만 더 길고 작동하기 위해 추가 입력이 많이 필요합니다. 또한 EdgeCycleMatrix다른 두 가지와 같이 재미있는 모양이 아닌 직사각형 배열이므로 나중에 도움이됩니다. )

행렬의 행을 계산하기 위해 항목의 계승을 취하여 모든 항목의 행렬로 바꾼 다음 추적을 수행합니다. (각 사이클에는 하나 이상의 모서리가 포함되므로 행 수보다 많은 열이 있으므로 열이 아닌 행을 계산합니다.)


1

MATL , 38 36 바이트

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

온라인으로 사용해보십시오! 온라인 컴파일러에서 입력 초과 시간이 초과되었습니다7.

설명

이 코드는 복소수로 궤도를 정의합니다. 여기서 허수 부분은 새 항 이고 실수 부분은 피보나치 시퀀스 의 이전 항 입니다. 각 복소수 값 은 시퀀스 의 상태 를 인코딩합니다 . 즉, a+jb다음 값이 주어지면 로 계산됩니다 b+j(a+b).

가능한 시작 값은 다음 a+jb으로 a, b[0, 1, ..., k-1]. 각 시작 값마다 코드가 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 , 196191 바이트

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가져 오기 를 피하고 제거 하는 방법을 찾을 수있는 경우 .

기본 아이디어는 "상태"(이전의 두 값을 포함하는 튜플) 목록을 생성하여주기 시작시기를 확인하는 것입니다. 그런 다음 각 궤도가 이전의 궤도와 다른지 확인합니다 (실제로 다른 방식으로 작동하지만 단어를 입력하기는 어렵습니다). 궤도가 같은지 확인하기 위해 우리는 길이가 같은지 그리고 하나가 다른 하나에 맞는지 여부를 확인합니다. 예를 들어 [0,2,2], [2,2,0]: 길이는 모두 3이며 연속 하위 시퀀스로 [0,2,2,0,2,2]포함 [2,2,0]됩니다. 그것이 바보인지 확실하지 않지만 작동하는 것 같습니다.

편집 : 5 바이트를 벗어난 Laikoni에게 감사드립니다! 더 많은 팁을 읽어보아야합니다.


1
이 팁 을 사용 하여 피할 수있는 것 같습니다 length. 또 다른 바이트에 저장할 수 있습니다 !|r<-p++[a]=r!b.
Laikoni

0

자바 스크립트 (ES6), 337 335 바이트

Ω (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 이상)를 계산할 때 TIO에서 60 초 제한을 초과했습니다.

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

설명 (비 골프)

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

자바 스크립트 (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

파이썬 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.