|
> No.993[元記事へ]
GAIさんへのお返事です。
例
1,2,3,4,5,6,7,8,9,10,11,12,13
↓
-9,-8,-7,1,2,4,5,6,-3,10,11,12,13
枚数列{6,3,4,9}の4手が最少手数のようです。
LET t0=TIME
PUBLIC NUMERIC N !カードの枚数
LET N=13
DIM c(N) !最初のパターン ※
DATA 1,2,3,4,5,6,7,8,9,10,11,12,13
MAT READ c
PUBLIC NUMERIC GOAL(100) !最終のパターン ※
MAT GOAL=ZER(N)
DATA -9,-8,-7,1,2,4,5,6,-3,10,11,12,13
MAT READ GOAL
PUBLIC NUMERIC LIMIT !手数の上限 ※
LET LIMIT=10
DIM A(LIMIT) !枚数
CALL backtrack(c,1,A)
PRINT "計算時間=";TIME-t0
END
EXTERNAL SUB reverse(c(),P) !先頭からP枚を裏返す
FOR i=1 TO INT(P/2) !交換
LET t=c(i)
LET c(i)=c(P-i+1)
LET c(P-i+1)=t
NEXT i
FOR i=1 TO P !反転
LET c(i)=-c(i)
NEXT i
END SUB
EXTERNAL SUB backtrack(c(),K,A()) !バックトラック法で検証する
IF K<=LIMIT THEN !手数の上限内なら
DIM x(N)
MAT x=c !save it
FOR i=1 TO N !枚数を変える
LET A(K)=i
CALL reverse(c,i) !反転
FOR j=1 TO N !最終のパターンかどうか確認する
IF c(j)<>GOAL(j) THEN EXIT FOR
NEXT j
IF j>N THEN !一致したら
LET LIMIT=K-1 !上限を狭める ※最初に見つかったもの
PRINT K;"手"
FOR j=1 TO K
PRINT A(j); !枚数
NEXT j
PRINT
!!!MAT PRINT c; !debug
ELSE
CALL backtrack(c,K+1,A) !次へ
END IF
MAT c=x !restore it
NEXT i
END IF
END SUB
|
|