攻略法の1つを示します。(必勝パターン)
!(111,222,333)→(123,231,312)型 ※N*(N-1)回
LET N=5 !成分の数
DIM P$(N) !各成分の初期値
FOR i=1 TO N
LET P$(i)=REPEAT$(fnSTR1$(i),N)
NEXT i
LET S=0 !第s手目
CALL PrintOut(S)
!●前半 - 右端へ収集する 計(N-1)+Σ[k=1,N-2]{k}=N*(N-1)/2回
!■前半の展開
! 目標 10手 (1234,234,34,4,555551111222334)
!Step.1 ※(N-1)回
! 右端成分に、1つずつ連続する数字の個数が少なくなるように「並び」の順に数字を集める。
LET y=N !xからyへ移動
FOR i=1 TO N-1
LET x=i
LET w$=RIGHT$(P$(x),N-i) !target
CALL move(x,y,w$,x) !move it
NEXT i
PRINT
!Step.2 ※Σ[k=1,N-2]{k}回
! 左端成分から右端手前の成分までは、残りの数字を使って、
! 各成分で1つずつ数字の個数が少なくなるように「並び」の順に数字を集める。
!理由
! (1,2-2,3-3-3,4-4-4-4,555551111222334)
! ↑ ↑ ↑
! 1個、2個、3個をそれぞれ移動させる
FOR k=1 TO N-2
LET x=k+1 !この位置の左側へ
LET w$=RIGHT$(P$(x),k) !target
FOR y=1 TO k
CALL move(x,y,w$,1) !move it
NEXT y
NEXT k
PRINT
PRINT
!●後半 - 右端 -5-5-5-51-1-1-12-2-23-34 を分配する Σ[k=1,N-1]{k}=N*(N-1)/2回
!■後半の展開
!・右端成分の数字列を「並び」になるように数字列を分割する。
! ※ハイフォンの数が移動回数となる。
!・その「並び」を置ける位置へ移動させる。最後の2文字を埋めるのは、「並び」が2文字に限る。
! 例 -51は、2番目の成分234を埋める。
! ※最終パターンを最後2文字が「並び」になるように分割する。これを目安にする。
!
! 目標 10手 (1234-5,234-51,34-5-12,4-5-1-23,5-1-2-34)
!
!理由
! -5-5-5-51 4個
! -1-1-12 3個
! -2-23 2個
! -34 1個をそれぞれ移動させる
LET x=N !右端の移動させる数字列
LET w$=RIGHT$(P$(x),N*(N+1)/2-1)
FOR k=N-1 TO 1 STEP -1
LET w1=fnVAL1(LEFT$(w$,1))
FOR j=1 TO k-1 !最初に1文字を埋める ※-5-5-5,-1-1,-2
FOR y=1 TO N !左端から一巡内で順に探す
LET t=LEN(P$(y))
!PRINT x;y;w$;L !debug
IF t>=N OR t=N-2 THEN !「N文字揃っている」か「残りが2文字」なら、スキップする
!nop
ELSE
LET pp=fnVAL1(RIGHT$(P$(y),1)) !結合部分が「並び」になるなら
IF pp+1=w1 OR pp+1=w1+N THEN
CALL move(x,y,w$,1) !move it
EXIT FOR
END IF
END IF
NEXT y
IF y>N THEN !場所がない(発生しないはず)
PRINT "アルゴリズムのエラーです。"
STOP
END IF
NEXT j
LET y=N-k+1 !最後に2文字を埋める ※-51,-12,-23,-34
CALL move(x,y,w$,2) !move it
NEXT k
SUB move(x,y,w$,L) !xからyへ移動
LET P$(x)=LEFT$(P$(x),LEN(P$(x))-LEN(w$)) !move it
LET P$(y)=P$(y)&w$
LET S=S+1 !dump it
CALL PrintOut(S)
LET x=y !配置位置を記録する
LET w$=RIGHT$(w$,LEN(w$)-L) !L文字切り出す。次へ
END SUB
SUB PrintOut(S) !成分を表示する
PRINT USING "### 手 ( ":S;
PRINT P$(1);
FOR t=2 TO N
PRINT ", ";P$(t);
NEXT t
PRINT " )";
PRINT USING " ## → ## ":x,y; !移動詳細
PRINT " ";w$
END SUB
!N進法表記
FUNCTION fnVAL1(x$) !1文字の数字を数値に変換する
LET fnVAL1=POS("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",x$)
END FUNCTION
FUNCTION fnSTR1$(x) !1桁の数値を数字に変換する
LET fnSTR1$=MID$("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",x+1,1)
END FUNCTION
END
実行結果
0 手 ( 11111, 22222, 33333, 44444, 55555 ) 0 → 0
1 手 ( 1, 22222, 33333, 44444, 555551111 ) 1 → 5 1111
2 手 ( 1, 22, 33333, 44444, 555551111222 ) 2 → 5 222
3 手 ( 1, 22, 333, 44444, 55555111122233 ) 3 → 5 33
4 手 ( 1, 22, 333, 4444, 555551111222334 ) 4 → 5 4
5 手 ( 12, 2, 333, 4444, 555551111222334 ) 2 → 1 2
6 手 ( 1233, 2, 3, 4444, 555551111222334 ) 3 → 1 33
7 手 ( 123, 23, 3, 4444, 555551111222334 ) 1 → 2 3
8 手 ( 123444, 23, 3, 4, 555551111222334 ) 4 → 1 444
9 手 ( 1234, 2344, 3, 4, 555551111222334 ) 1 → 2 44
10 手 ( 1234, 234, 34, 4, 555551111222334 ) 2 → 3 4
11 手 ( 123455551111222334, 234, 34, 4, 5 ) 5 → 1 55551111222334
12 手 ( 12345, 234, 345551111222334, 4, 5 ) 1 → 3 5551111222334
13 手 ( 12345, 234, 345, 4551111222334, 5 ) 3 → 4 551111222334
14 手 ( 12345, 23451111222334, 345, 45, 5 ) 4 → 2 51111222334
15 手 ( 12345, 23451, 345, 45111222334, 5 ) 2 → 4 111222334
16 手 ( 12345, 23451, 345, 451, 511222334 ) 4 → 5 11222334
17 手 ( 12345, 23451, 3451222334, 451, 51 ) 5 → 3 1222334
18 手 ( 12345, 23451, 34512, 451, 5122334 ) 3 → 5 22334
19 手 ( 12345, 23451, 34512, 4512334, 512 ) 5 → 4 2334
20 手 ( 12345, 23451, 34512, 45123, 51234 ) 4 → 5 34