모든 크기의 데크를 완벽하게 섞을 수있는 사이클 길이


10

도전

가장 짧은 코드 양에서 :

  1. 모든 크기의 n ( n ≥ 2 및 n 은 짝수) 인 카드 데크에서 완벽한 셔플의 순열주기 길이를 계산합니다 .
  2. 2 ≤ n ≤ 1000 ( n 짝수) 동안 모든 사이클 길이의 테이블을 출력합니다 .

완벽한 셔플을 정의하는 두 가지 기본 방법이 있습니다. 첫 번째 카드를 맨 위에 놓고 마지막 카드를 맨 아래에 유지 하는 아웃 셔플 이 있으며 첫 번째 카드 와 마지막 카드를 중앙으로 한 위치 이동시키는 셔플 이 있습니다. 셔플 중 또는 셔플 중 하나를 수행 할 수 있습니다. 알고리즘은 둘 사이에서 거의 동일합니다.

  • 10 장 카드 덱의 셔플 : [1,2,3,4,5,6,7,8,9,10] ↦ [1,6,2,7,3,8,4,9,5, 10].
  • 10 장 카드 덱의 셔플 : [1,2,3,4,5,6,7,8,9,10] ↦ [6,1,7,2,8,3,9,4,10, 5].

그래픽 예

여기서 우리 는 20 장의 카드 덱에서 아웃 셔플 의주기 길이가 18 단계임을 알 수 있습니다. (이것은 단지 설명을위한 것이며 솔루션은 그래픽으로 사이클을 출력 할 필요가 없습니다.) 반면 클래식 52 카드 데크는 셔플 사이클 길이가 8 단계에 불과합니다 (표시되지 않음).

20 장의 카드 덱을위한 아웃 셔플 사이클

에서 셔플 20 카드 갑판은 6 단계의주기 길이를 가지고있다.

20 장의 카드 데크에 대한 셔플주기

출력의 표 예

가장 좋아하는 표 형식을 선택할 수 있지만 프로그램은 이와 비슷한 것을 출력해야합니다. 이것은 셔플 아웃입니다.

2 1
4 2
6 4
8 3
10 6
12 10
14 12
16 4
18 8
20 18
22 6
24 11
26 20
28 18
30 28
32 5
34 10
36 12
38 36
40 12
...many lines omitted...
1000 36

질문

  1. n 이 2의 거듭 제곱 일 때 숫자 입력 n 과 사이클 수 사이에 연결이있는 것 같 습니까?
  2. n 이 2의 거듭 제곱이 아닌 경우 는 어떻습니까?
  3. 흥미롭게도 1000 카드 데크의 아웃 셔플 사이클 수는 36이고 500 카드 데크의 아웃 셔플 사이클 수는 166입니다. 왜 그런가요?
  4. 사이클 카운트 cn 보다 크게 작은 최대 값은 무엇입니까? 즉, n / c 비율 이 최대화됩니다.


그래, 결과를 보여주는 것이 더 중요하다. 이 질문은 n 값에 대한 테이블을 생성하는 것입니다 . 본질적으로 더 수학적입니다.
Todd Lehman

나는 잠시 동안 입증 된 6/8 사이클과 나를 혼동했다 :) (내 구현이 잘못되었다고 생각했다). 마지막으로 이미지를보고 6주기라는 것을 알았으므로 편집했습니다. 웃긴
자랑스런 Haskeller

@proud haskeller — 아, 감사합니다!
Todd Lehman

1
시퀀스 A002326 입니다.
orlp

답변:


6

하스켈, 47 46 44 (셔플)

[[i|i<-[1..],mod(2^i)n<2]!!0|n<-[3,5..1001]]

기본 구현은 곱셈 그룹의 계수에서 2의 차수라는 것입니다 n+1.


1
당신은 제거 할 수 있습니다 l=- 표현 자체가 충분하다. 대화식 명령 행에서 실행할 때 유효한 프로그램입니다.
orlp


2

Pyth, 22 바이트

V500,JyhNl{.u.iFc2NJUJ

온라인으로 시연하십시오 . 500이 너무 느리면 더 작은 숫자로 바꾸십시오.

설명:

V500                     for N in [0, 1, ..., 499]:
      yhN                   (N + 1) * 2
     J                      assign to J
           .u      JUJ      apply the following expression J times
                            to N, starting with N = [0, 1, ..., J - 1],
                            and return all intermediate results:
                c2N            split N into 2 halfs
             .iF               and interleave them
         l{                 remove duplicates and give length
    ,                       make a pair and print

1
덱을 섞고 계산하는 실제 작업을 수행하는 pyth 솔루션이 결과를 즉시 예측할 수있는 쉬운 공식을 사용하는 haskell 솔루션의 절반에 불과한 것은 미친 일입니다.
Falco

@Falco 나는 알고있다
자랑스런 Haskeller

1
@ Falco 나는 실제로 내 대답의 pyth port를 시도했지만 그것을 수행하는 방법을 알 수 없었습니다. 그래서 방금 pyth를 30 분 동안 플레이하게되었습니다
자랑스런 Haskeller

<> <을 (를) 시도하지 않은 것을 기쁘게 생각하십시오
Falco

2

매스 매 티카, 53 (셔플)

Grid[{2#,MultiplicativeOrder[2,2#+1]}&/@Range[1,500]]

또는, 비폭력 적으로 이격되지 않은

Grid[{2 #, MultiplicativeOrder[2, 2 # + 1]} & /@ Range[1, 501]]

산출:

   2    2
   4    4
   6    3
   8    6
  10   10
  12   12
  14    4
  16    8
  18   18
  20    6
 (* digits, digits, bo bidgits, banana fana, ... *)
  498  166
  500  166
 (* skip a bit, brother ...  *)
  998   36
 1000   60

두 열의 모든 항목은 열의 가로 중앙에 있지만 분수 공간이 없습니다 &#8194;... &#8202;여기서 복제 할 수 있습니다.

관찰 :

  • 셔플 아웃은 2 장의 카드가 작은 데크에서 셔플입니다. (첫 번째 카드와 마지막 카드는 셔플 아웃 데모 전체에서 고정 된 위치에 있습니다.) 결과적으로 두 가지 옵션을 선택하면 비슷한 출력 목록이 표시됩니다. 두 번째 열은 한 행씩 이동합니다. 힌트 "두 가지의 힘"관련하여, 인 - 셔플 두 데크의 힘의 패턴이 {2^n - 2, n}, {2^n, 2n}. ( 2^n와 셔플 아웃 페어 n)
  • 셔플 예 2에서 갑판의 가장 가까운 끝으로부터의 거리가 각 단계에서 두 배가되는 것을 관찰하십시오 . {2, 4, 8, 15 = -5, -10, -20}. 실제로 이것은 모든 카드에 적용됩니다. 그러므로 우리 는 카드의 수가 어디에 있는지 21수정 하기 위해 어떤 힘 이 일치 하는지 알아야 합니다. (이 예에서 마지막 열 column의 카드 는 두 번째 열로 두 배가됩니다. 즉 , 갑판에있는 것보다 하나 이상의 카드와 일치하므로 "mod "입니다.) 따라서 MultiplicativeOrder [] 기능은 갈 길입니다 (Mathematica에서).n+1n-1-20n+1
  • 기본적으로 Grid [] 대신 TableForm []을 시도하지만 출력은 비슷합니다.

귀하의 예제 출력이 잘못 된 것 같습니다
자랑스럽게 haskeller

@proudhaskeller : 셔플 또는 아웃 셔플? 허용됩니다. (그리고 언급 한 바와 같이, 하나는 다른 쪽의 오른쪽 열에있는 한 행 이동입니다.)
Eric Towers

둘 다 맞지 않는 것 같습니다. 질문에서 예제 출력을 찾아보십시오. 어쩌면 귀하의 예제 출력이 잘못되어 실제 코드가 정확하고 예제가 구식 일뿐입니다. 모르지만 적합하지 않은 것 같습니다.
자랑스런 Haskeller

proudhaskeller : "8"에 출력 예제를 입력 한 것 같습니다. 그리고 적어도 한 번은 안팎으로 혼잡했습니다. 편집. 지속적으로 감사합니다. :-)
Eric Towers

0

C, 86 (또는 84)

점수는 명확성을 위해 포함 된 불필요한 공백을 제외합니다.

i,j,n;
main(){
  for(;n<1002;printf("%d %d\n",n,j),n+=2)
    for(i=n,j=1;i=i*2%(n+1),i-n;)j++;
}

이것은 다른 사람들이 지적한 것처럼 셔플이며 양쪽 끝의 고정 카드가 제거 된 아웃 셔플입니다.

다른 사람들이 지적한 바와 같이, 셔플에서 각 카드의 위치는 매번 두 배가되지만, 이것은 modulo이어야합니다 n+1. 여분의 카드 위치는 테이블 왼쪽의 0 위치라고 생각합니다 (이 카드는 고정 카드를 모두 셔플에서 고정하는 것으로 생각할 수 있습니다). 분명히 카드의 위치는 항상 양수 여야하므로 셔플 케이스의 경우 0 위치는 항상 비어 있습니다.

코드 i는의 값으로 초기화 됩니다 n. 그런 다음 2를 곱하고 결과 모드를 가져 와서 초기 값으로 돌아 왔는지 (n+1)확인 i합니다 ( i-n0). j마지막 반복을 제외하고 각 반복에 대해 증가 합니다 (따라서 j1로 초기화해야 함 ).

원칙적으로, 끝에서 비교 된 i1..n이 같은 숫자로 설정되어 있는지 확인 하는 한 범위 내의 값을 가질 수 있습니다 . 선택의 이유 n는 프로그램이 사건에 적합한 지 확인하는 것이 었습니다 n==0. 문제는 임의의 수 모듈로 (0+1)가 0 이므로이 경우 루프 i가 1과 같은 상수로 초기화 되면 결코 종료되지 않는다는 것 입니다.

질문 예에는 n==2아웃 셔플에 해당하는 대소 문자가 포함 되므로이 경우가 필요하다고 해석되었습니다. 그렇지 않은 경우 와 같은 값인 1 n,로 초기화 i하여 2 바이트를 절약 할 수 있습니다 j.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.