|
!シャッフルについて調べていたら、このページに
!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
|
|