シャッフルについて調べていたら

 投稿者:SECOND  投稿日:2008年12月29日(月)07時01分26秒
  !シャッフルについて調べていたら、このページに
!GAI さんの調査された表と、その下の方に、C言語の検証プログラムが
!ありましたので、十進BASIC でも動くように書き直してみました。
!勝手に加筆して、結果に、おかしな数字が、出たりしていないでしょうか。

!#include <stdio.h>
!#include <string.h>
!int buf[1000], bufw[1000];
!int n;

!void shuffle(void)
!{
! int i;
! memcpy(bufw, buf, sizeof(buf[0]) * n);
! for(i = 0; i < n; ++i)
!  buf[i] = bufw[i / 2 + (i + 1) % 2 * n / 2];
!}

!int main(void)
!{
! int i, c, cc;
! for(n = 2; n <= 1000; n += 2){
!  for(i = 0; i < n; ++i)
!   buf[i] = i;
!  cc = c = 0;
!  do{
!   ++c;
!   shuffle();
!   for(i = 0; i < n; ++i)
!    if(buf[i] != n - 1 - i)
!     break;
!   if(i >= n && cc == 0)
!    cc = c;
!   for(i = 0; i < n; ++i)
!    if(buf[i] != i)
!     break;
!  }while(i < n);
!  printf("%3d %3d %3d\n", n, c, cc);
! }
! return 0;
!}

!----------------------------
!十進BASIC に移植。
! i=0~n-1 は、見づらいので i=1~n その他 無断加筆、ご容赦 )

LET maxim=13 ! 最大枚数 2~1000
DIM buf(1000), bufw(1000)

SUB in_riffle_shuffle !インのリフル。奇数枚は、後半を1枚多め
   MAT bufw=buf
   FOR i=1 TO n
      LET buf(i)= bufw(CEIL(i/2)+MOD(i,2)*INT(n/2)) !1234→3142, 12345→31425
   NEXT i
END SUB

SUB out_riffle_shuffle !アウトのリフル。奇数枚は、前半を1枚多め
   MAT bufw=buf
   FOR i=1 TO n
      LET buf(i)= bufw(CEIL(i/2)+MOD(i+1,2)*CEIL(n/2)) !1234→1324, 12345→13243
   NEXT i
END SUB

FOR n=2 TO maxim !STEP 2 ! Step を外せば奇数も計算。
!-----
   MAT buf=ZER(n) ! 配列サイズ調整、追加
   !-----
   FOR i=1 TO n
      LET buf(i)= i
   NEXT i
   LET cc=0
   LET c=0
   !-----
   IF maxim<15 THEN MAT PRINT USING REPEAT$(" ###",n) :buf ! 表示、追加
   !-----
   DO
      LET c=c+1
      CALL in_riffle_shuffle ! 1234→3142, 12345→31425
      !CALL out_riffle_shuffle ! 1234→1324, 12345→13243
      !-----
      IF maxim<15 THEN MAT PRINT USING REPEAT$(" ###",n) :buf ! 表示、追加
      !-----
      FOR i=1 TO n
         IF buf(i)<> n+1-i THEN EXIT FOR
      NEXT i
      IF i>n AND cc=0 THEN LET cc=c
      FOR i=1 TO n
         IF buf(i)<>i THEN EXIT FOR
      NEXT i
   LOOP UNTIL i>n
   PRINT USING "枚数=### 同順=### 逆順=###(復元回数)": n, c, cc
   IF maxim<15 THEN PRINT ! 表示、追加
NEXT n

END
 

戻る