Maxima を使って、数独表(*1を発生させる関数を定義してみました。ファイル sudoku.mac を適当なフォルダ(*2に置いて、以下のように実行します。
(%i1) load("sudoku.mac");
(%o1) sudoku.mac
(%i2) sudoku();
[ 9 2 1 5 3 7 6 8 4 ]
[ ]
[ 4 3 7 8 2 6 1 5 9 ]
[ ]
[ 6 8 5 4 9 1 3 2 7 ]
[ ]
[ 2 1 8 7 6 9 4 3 5 ]
[ ]
(%o2) [ 3 9 4 2 8 5 7 6 1 ]
[ ]
[ 7 5 6 1 4 3 2 9 8 ]
[ ]
[ 5 4 9 3 7 2 8 1 6 ]
[ ]
[ 8 6 3 9 1 4 5 7 2 ]
[ ]
[ 1 7 2 6 5 8 9 4 3 ]
生成できなかった場合は -1 を返します。5 割くらいの確率で失敗します(^^;。
*1) 数独ルールにのっとって 81 個の数字を並べた表のことを数独表と呼ぶことにします。
*2) Windows の場合は C:\Documents and Settings\User Name に置きます。
数独のルールは、
- 縦横に 1 から 9 までの 9 個の数字を 9 個ずつ並べる。
- ただし、縦一列、横一列に同じ数字を使ってはいけない。
- さらに、各ブロックにも同じ数字を使ってはいけない。
というものでした。
9 |
2 |
1 |
5 |
3 |
7 |
6 |
8 |
4 |
4 |
3 |
7 |
8 |
2 |
6 |
1 |
5 |
9 |
6 |
8 |
5 |
4 |
9 |
1 |
3 |
2 |
7 |
2 |
1 |
8 |
7 |
6 |
9 |
4 |
3 |
5 |
3 |
9 |
4 |
2 |
8 |
5 |
7 |
6 |
1 |
7 |
5 |
6 |
1 |
4 |
3 |
2 |
9 |
8 |
5 |
4 |
9 |
3 |
7 |
2 |
8 |
1 |
6 |
8 |
6 |
3 |
9 |
1 |
4 |
5 |
7 |
2 |
1 |
7 |
2 |
6 |
5 |
8 |
9 |
4 |
3 |
【数独表生成法】
sudoku.mac で用いている数独表生成法を簡単に述べると、次のようになります。
- STEP1-1 第 1 行のランダムな位置に 1 を入れる。
- STEP1-2 第 2 行のランダムな位置に 1 を入れる。ただし、第 1 行の 1 と同じブロックを除く。
- STEP1-3 第 3 行のランダムな位置に 1 を入れる。ただし、第 1 行及び第 2 行の 1 と同じブロックを除く。
- STEP1-4 第 4 行のランダムな位置に 1 を入れる。ただし、第 1 行から第 3 行までの 1 と同じ列を除く。
- STEP1-5 第 5 行のランダムな位置に 1 を入れる。ただし、第 1 行から第 3 行までの 1 と同じ列を除く。さらに、第 4 行の 1 と同じブロックを除く。
- ..... 以下同様に第 9 行まで 1 を入れる。
- STEP2-1 第 1 行のランダムな位置に 2 を入れる。ただし、1 が入っている場所を除く。
- .....
この操作を
STEP9-9 まで実行します。この方法はたびたび破綻します。そこで、
STEPi-j で破綻した場合、
STEPi-1 まで遡って処理を繰り返し、100 回破綻した場合には -1 を返すようにしています。
【ブロックインデックスとラインインデックス】
上記の手順を実装する場合、各数字が「第何行目の第何列目か」と「第何ブロックの何番目か」を常に把握する必要があります。そこで、前者をラインインデックス(マトリックスインデックス)、後者をブロックインデックスと呼ぶことにし、
ラインインデックス |
|
ブロックインデックス |
[1,1] |
[1,2] |
[1,3] |
[1,4] |
[1,5] |
[1,6] |
[1,7] |
[1,8] |
[1,9] |
[2,1] |
[2,2] |
[2,3] |
[2,4] |
[2,5] |
[2,6] |
[2,7] |
[2,8] |
[2,9] |
[3,1] |
[3,2] |
[3,3] |
[3,4] |
[3,5] |
[3,6] |
[3,7] |
[3,8] |
[3,9] |
[4,1] |
[4,2] |
[4,3] |
[4,4] |
[4,5] |
[4,6] |
[4,7] |
[4,8] |
[4,9] |
[5,1] |
[5,2] |
[5,3] |
[5,4] |
[5,5] |
[5,6] |
[5,7] |
[5,8] |
[5,9] |
[6,1] |
[6,2] |
[6,3] |
[6,4] |
[6,5] |
[6,6] |
[6,7] |
[6,8] |
[6,9] |
[7,1] |
[7,2] |
[7,3] |
[7,4] |
[7,5] |
[7,6] |
[7,7] |
[7,8] |
[7,9] |
[8,1] |
[8,2] |
[8,3] |
[8,4] |
[8,5] |
[8,6] |
[8,7] |
[8,8] |
[8,9] |
[9,1] |
[9,2] |
[9,3] |
[9,4] |
[9,5] |
[9,6] |
[9,7] |
[9,8] |
[9,9] |
|
|
[1,1] |
[1,2] |
[1,3] |
[2,1] |
[2,2] |
[2,3] |
[3,1] |
[3,2] |
[3,3] |
[1,4] |
[1,5] |
[1,6] |
[2,4] |
[2,5] |
[2,6] |
[3,4] |
[3,5] |
[3,6] |
[1,7] |
[1,8] |
[1,9] |
[2,7] |
[2,8] |
[2,9] |
[3,7] |
[3,8] |
[3,9] |
[4,1] |
[4,2] |
[4,3] |
[5,1] |
[5,2] |
[5,3] |
[6,1] |
[6,2] |
[6,3] |
[4,4] |
[4,5] |
[4,6] |
[5,4] |
[5,5] |
[5,6] |
[6,4] |
[6,5] |
[6,6] |
[4,7] |
[4,8] |
[4,9] |
[5,7] |
[5,8] |
[5,9] |
[6,7] |
[6,8] |
[6,9] |
[7,1] |
[7,2] |
[7,3] |
[8,1] |
[8,2] |
[8,3] |
[9,1] |
[9,2] |
[9,3] |
[7,4] |
[7,5] |
[7,6] |
[8,4] |
[8,5] |
[8,6] |
[9,4] |
[9,5] |
[9,6] |
[7,7] |
[7,8] |
[7,9] |
[8,7] |
[8,8] |
[8,9] |
[9,7] |
[9,8] |
[9,9] |
|
これらの間の相互変換関数 LtoB(x, y)、BtoL(x, y) を作成します。ラインインデックスの [i,j] を L[i,j]、ブロックインデックスの [i,j] を B[i,j] と書くことにします(プログラムの中では 2 次元リスト L[i][j]、B[i][j] にしています)。
【関数 LtoB(x, y)】
関数 LtoB(x, y) を作成するため、便宜上、ラインインデックスの各インデックスに一律に 2 を加えて考えます。例えば、L[7,6] は
B[8,3] に対応しますが、2 を加えて考えるので、L+[9, 8] = B[8, 3] となります(2 を加えたインデックスを + 記号をつけて表しています)。まずはじめに、L+[9, 8] に対応するブロック数 8 を求めてみます。3 による割り算
9 ÷ 3 = 3 … 0 および 8 ÷ 3 = 2 … 2
の商に注目し、(3-1) × 3 + 2 = 8 により求まります。要するに、自分自身が属しているのは、上から何ブロック目か、そして、左から何ブロック目かを求めればよいわけです。
ラインインデックス+
[3,3] |
[3,4] |
[3,5] |
[3,6] |
[3,7] |
[3,8] |
[3,9] |
[3,10] |
[3,11] |
[4,3] |
[4,4] |
[4,5] |
[4,6] |
[4,7] |
[4,8] |
[4,9] |
[4,10] |
[4,11] |
[5,3] |
[5,4] |
[5,5] |
[5,6] |
[5,7] |
[5,8] |
[5,9] |
[5,10] |
[5,11] |
[6,3] |
[6,4] |
[6,5] |
[6,6] |
[6,7] |
[6,8] |
[6,9] |
[6,10] |
[6,11] |
[7,3] |
[7,4] |
[7,5] |
[7,6] |
[7,7] |
[7,8] |
[7,9] |
[7,10] |
[7,11] |
[8,3] |
[8,4] |
[8,5] |
[8,6] |
[8,7] |
[8,8] |
[8,9] |
[8,10] |
[8,11] |
[9,3] |
[9,4] |
[9,5] |
[9,6] |
[9,7] |
[9,8] |
[9,9] |
[9,10] |
[9,11] |
[10,3] |
[10,4] |
[10,5] |
[10,6] |
[10,7] |
[10,8] |
[10,9] |
[10,10] |
[10,11] |
[11,3] |
[11,4] |
[11,5] |
[11,6] |
[11,7] |
[11,8] |
[11,9] |
[11,10] |
[11,11] |
次に、ブロック内番号 3 を求めてみます。今度は、3 による割り算
9 ÷ 3 = 3 … 0 および 8 ÷ 3 = 2 … 2
の余りに注目し、0 × 3 + (2 + 1) = 3 により求まります。
【関数 BtoL(x, y)】
関数 LtoB(x, y) の場合と同様、便宜上、ブロックデックスの各インデックスに一律に 2 を加えて考えます。
ブロックインデックス+
[3,3] |
[3,4] |
[3,5] |
[4,3] |
[4,4] |
[4,5] |
[5,3] |
[5,4] |
[5,5] |
[3,6] |
[3,7] |
[3,8] |
[4,6] |
[4,7] |
[4,8] |
[5,6] |
[5,7] |
[5,8] |
[3,9] |
[3,10] |
[3,11] |
[4,9] |
[4,10] |
[4,11] |
[5,9] |
[5,10] |
[5,11] |
[6,3] |
[6,4] |
[6,5] |
[7,3] |
[7,4] |
[7,5] |
[8,3] |
[8,4] |
[8,5] |
[6,6] |
[6,7] |
[6,8] |
[7,6] |
[7,7] |
[7,8] |
[8,6] |
[8,7] |
[8,8] |
[6,9] |
[6,10] |
[6,911] |
[7,9] |
[7,8] |
[7,11] |
[8,9] |
[8,10] |
[8,11] |
[9,3] |
[9,4] |
[9,5] |
[10,3] |
[10,4] |
[10,5] |
[11,3] |
[11,4] |
[11,5] |
[9,6] |
[9,7] |
[9,8] |
[10,6] |
[10,7] |
[10,8] |
[11,6] |
[11,7] |
[11,8] |
[9,9] |
[9,10] |
[9,11] |
[10,9] |
[10,10] |
[10,11] |
[11,9] |
[11,10] |
[11,11] |
B+[11,10] に対応する L[9,8] を求めてみましょう。行番号 9 を求めるためには、ブロック番号 11 とブロック内番号 10 の 3 による割り算
11 ÷ 3 = 3 … 2 および 10 ÷ 3 = 3 … 1
の商に注目し、(3-1) × 3 + 3 = 9 により求まります。また、列番号 8 を求めるには、3 による割り算
11 ÷ 3 = 3 … 2 および 10 ÷ 3 = 3 … 1
の余りに注目し、2 × 3 + (1 + 1) = 8 により求まります。すなわち、LtoB(x, y) と BtoL(x, y) はまったく同じ計算により定義できます。
【関数 BtoL(x, y)=LtoB(x, y) 動作確認】
sudoku.mac では関数 Btol(x, y)=LtoB(x, y) は関数名 f(x, y) で定義されています。
1
2
3
4
5
|
f(x, y) := block([dx, dy],
dx: divide(x + 2, 3),
dy: divide(y + 2, 3),
[dx[1] * 3 + dy[1] - 3, dx[2] * 3 + dy[2] + 1]
);
|
|
正しく定義できているか、確認しておきます。入力済みのファイル
sudoku_pre.mac を読み込んで実験してみましょう。
(%i1) load("sudoku_pre.mac");
(%o1) sudoku_pre.mac
(%i2) lambda([i, j], j+9*(i-1));
(%o2) lambda([i, j], j + 9 (i - 1))
(%i3) A: genmatrix(%, 9, 9, 1, 1);
[ 1 2 3 4 5 6 7 8 9 ]
[ ]
[ 10 11 12 13 14 15 16 17 18 ]
[ ]
[ 19 20 21 22 23 24 25 26 27 ]
[ ]
[ 28 29 30 31 32 33 34 35 36 ]
[ ]
(%o3) [ 37 38 39 40 41 42 43 44 45 ]
[ ]
[ 46 47 48 49 50 51 52 53 54 ]
[ ]
[ 55 56 57 58 59 60 61 62 63 ]
[ ]
[ 64 65 66 67 68 69 70 71 72 ]
[ ]
[ 73 74 75 76 77 78 79 80 81 ]
(%i4) B: zeromatrix(9, 9)$
(%i5) for i: 1 thru 9 do for j: 1 thru 9 do
B[i][j]: A[f(i, j)[1]][f(i, j)[2]];
(%o5) done
(%i6) display(B);
[ 1 2 3 10 11 12 19 20 21 ]
[ ]
[ 4 5 6 13 14 15 22 23 24 ]
[ ]
[ 7 8 9 16 17 18 25 26 27 ]
[ ]
[ 28 29 30 37 38 39 46 47 48 ]
[ ]
B = [ 31 32 33 40 41 42 49 50 51 ]
[ ]
[ 34 35 36 43 44 45 52 53 54 ]
[ ]
[ 55 56 57 64 65 66 73 74 75 ]
[ ]
[ 58 59 60 67 68 69 76 77 78 ]
[ ]
[ 61 62 63 70 71 72 79 80 81 ]
(%o6) done
(%i7) C: zeromatrix(9, 9)$
(%i8) for i: 1 thru 9 do for j: 1 thru 9 do
C[i][j]: B[f(i, j)[1]][f(i, j)[2]];
(%o8) done
(%i9) display(C);
[ 1 2 3 4 5 6 7 8 9 ]
[ ]
[ 10 11 12 13 14 15 16 17 18 ]
[ ]
[ 19 20 21 22 23 24 25 26 27 ]
[ ]
[ 28 29 30 31 32 33 34 35 36 ]
[ ]
C = [ 37 38 39 40 41 42 43 44 45 ]
[ ]
[ 46 47 48 49 50 51 52 53 54 ]
[ ]
[ 55 56 57 58 59 60 61 62 63 ]
[ ]
[ 64 65 66 67 68 69 70 71 72 ]
[ ]
[ 73 74 75 76 77 78 79 80 81 ]
(%o9) done
まず、単純に 1 から 81 までの数字を並べた行列 A を作成します。これを、先の関数 f(x, y) を利用し、ブロック型に並べ替えた行列が B です。再び関数 f(x, y) を利用し、行列 B をライン型に並べ替えたものが行列 C です。行列 A と C が一致していることから関数 f が正しく定義できていることがわかります。
【出来ることからコツコツと】
準備が整ったところで、いよいよ数独表生成関数を作成していきましょう。まずは手始めに、単純に各行に 1 を入れていくだけの関数 sudoku_pre1() を定義してみます。
1
2
3
4
5
6
7
8
9
|
sudoku_pre1() := ([a,
M: zeromatrix(9, 9)
],
for i: 1 thru 9 do (
a: random(9) + 1,
M[i][a]: 1
),
M
);
|
|
あまりに単純すぎて解説の余地はありませんが、まず、0 で埋め尽くした行列 M を用意しておき(
2 行目)、第 1 行 M[1]、第 2 行 M[2]、..... に順に 1 を入れていきます(
6 行目)。この関数の実行例は、下記の通りです。
(%i10) sudoku_pre1();
[ 0 0 1 0 0 0 0 0 0 ]
[ ]
[ 0 0 0 0 0 0 1 0 0 ]
[ ]
[ 0 0 1 0 0 0 0 0 0 ]
[ ]
[ 0 0 0 0 0 1 0 0 0 ]
[ ]
(%o10) [ 0 1 0 0 0 0 0 0 0 ]
[ ]
[ 0 1 0 0 0 0 0 0 0 ]
[ ]
[ 0 0 0 0 0 1 0 0 0 ]
[ ]
[ 0 0 0 0 0 0 0 0 1 ]
[ ]
[ 0 0 0 0 0 0 1 0 0 ]
当然ながら、同じブロックや同じ列に複数の 1 が入ってしまっています。そこで、次のステップとして、同じ列に 1 が入るのを避けてみましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
sudoku_pre2() := ([a, p,
M: zeromatrix(9, 9),
K: zeromatrix(9, 9)
],
for i: 1 thru 9 do (
p: 0,
for j: 1 while (p = 0) do (
a: random(9) + 1,
if K[i][a] = 0 then (
p: 1,
for k: i thru 9 do K[k][a]: 1,
M[i][a]: 1
)
)
),
M
);
|
|
1 を「入れていい場所」と「入れてはいけない場所」を記録する変数(行列)K(
3 行目)を用意するところがポイントです。
7 行目の j はダミー変数で、変数 p が 0 でなくなるまでループを実行し続けます。ここで、変数 p は、「1 を入れていい列」が見つかった場合に
1 が代入される変数です。その判断をしているのが
9 行目の if 文です。「1 を入れていい列」が見つかると、変数 p に 1 を代入すると同時に、「もうこれ以上同じ列には 1 を入れてはいけない」ことを表すために、変数
K の当該列を 1 で埋め尽くします(
11 行目)。最後に、1 を代入し(
12 行目)、
7 行目の for ループを抜け、次の i が実行されます(
5 行目の for ループ)。
続いて、同じブロックに 1 が入らないようにする処理を追加ます。M[i][a] に対応するブロック番号は f(i, a)[1] で求まりますから、
for k: 1 thru 9 do (d: f(f(i, a)[1], k), K[d[1]][d[2]]: 1)
のような for ループを挿入すればよいでしょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
sudoku_pre3() := ([a, p, d,
M: zeromatrix(9, 9),
K: zeromatrix(9, 9)
],
for i: 1 thru 9 do (
p: 0,
for j: 1 while (p = 0) do (
a: random(9) + 1,
if K[i][a] = 0 then (
p: 1,
for k: 1 thru 9 do (
d: f(f(i, a)[1], k),
K[d[1]][d[2]]: 1
),
for k: i thru 9 do K[k][a]: 1,
M[i][a]: 1
)
)
),
M
);
|
|
11 行から
14 行に挿入してみました。この関数 sudoku_pre3() を実行すると、次のようになります。
(%i11) sudoku_pre3();
[ 0 0 0 0 0 0 0 1 0 ]
[ ]
[ 0 0 0 0 0 1 0 0 0 ]
[ ]
[ 0 1 0 0 0 0 0 0 0 ]
[ ]
[ 0 0 0 0 0 0 0 0 1 ]
[ ]
(%o11) [ 0 0 0 0 1 0 0 0 0 ]
[ ]
[ 1 0 0 0 0 0 0 0 0 ]
[ ]
[ 0 0 0 1 0 0 0 0 0 ]
[ ]
[ 0 0 1 0 0 0 0 0 0 ]
[ ]
[ 0 0 0 0 0 0 1 0 0 ]
ブロックごとの色分けをしていないのでわかりにくいですが、確かに各ブロックとも 1 個づつ 1 が入っています。もちろん、同じ列にも 1 は 1 個だけです。
【失敗は成功の前触れである】
とりあえず関数 sudoku_pre3() で 1 を入れることができましたから、後はこれを 1 から 9 までループを回せば目的の関数が完成しそうです。そこで、次のような関数 sudoku_pre4() を作ってみました。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
sudoku_pre4() := ([a, p, d,
M: zeromatrix(9, 9),
K: zeromatrix(9, 9)
],
for l: 1 thru 9 do (
for i: 1 while(i <= 9) do (
p: 0,
for j: 1 while (p = 0) do (
a: random(9) + 1,
if K[i][a] = 0 then (
p: 1,
for k: 1 thru 9 do (
d: f(f(i, a)[1], k),
K[d[1]][d[2]]: 1
),
for k: i thru 9 do K[k][a]: 1,
M[i][a]: l
)
)
),
K: copymatrix(M)
),
M
);
|
|
これまで 1 に固定していた「入れる数 1」を変数 l に変更したこと(
5 行目と
17 行目)と、変数 i に関するループ(
6 行目)を抜ける度に変数 K を変数 M で置き換える処理(
21 行目)を加えただけです。しかし、この関数は無限ループに入るので絶対に
実行しないでください。途中で、
10 行目の K[i][a]=0 を満たす a が存在しなくなり、いつまで経っても p が 1 にならないからです。関数 sudoku_pre4()
が破綻する様子を見ておきましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
sudoku_pre5() := ([a, p, d, q,
M: zeromatrix(9, 9),
K: zeromatrix(9, 9)
],
for l: 1 thru 9 do (
q: 0,
for i: 1 while (i <= 9 and q = 0) do (
p: 0,
for j: 1 while (p = 0 and q = 0) do (
a: random(9) + 1,
if not member(0, K[i]) then (
q: 1
) else (
if K[i][a] = 0 then (
p: 1,
for k: 1 thru 9 do (
d: f(f(i, a)[1], k),
K[d[1]][d[2]]: 1
),
for k: i thru 9 do K[k][a]: 1,
M[i][a]: l
)
)
)
),
K: copymatrix(M)
),
M
);
|
|
新変数 q を用意し(
6 行目)、「入れる場所」がなくなったら 1 を代入し(
11 行から
13 行)、各ループを抜けるように調整しました(
7 行目と
9 行目の for ループ)。早速実行してみましょう。
(%i12) sudoku_pre5();
[ 4 5 6 1 9 8 7 2 3 ]
[ ]
[ 3 1 7 2 0 4 6 8 5 ]
[ ]
[ 0 2 8 3 5 6 0 4 1 ]
[ ]
[ 5 0 3 4 8 0 1 6 2 ]
[ ]
(%o12) [ 6 4 2 5 1 0 3 0 8 ]
[ ]
[ 8 0 1 6 3 2 4 5 0 ]
[ ]
[ 1 8 0 0 4 5 2 3 6 ]
[ ]
[ 2 3 0 8 6 0 5 1 4 ]
[ ]
[ 0 6 4 0 2 1 8 0 0 ]
1、2、4、6、8 については最終行(第 9 行)まで完了していますが、3 と 5 については第 8 行まで完了し、最終行で破綻しています。あと一歩でした。7 については第 3 行で早々と破綻し、9 にいたっては第 2 行で破綻というありさまです。この結果をどう捕らえるかで今後の方針が大きく異なります。
- 端にも棒にも着かない。
- 望みは薄いが、見込みがないと断言するには至らない。
- 脈ありと見る。
- 間違いなく改善できる。
端にも棒にも.....と見るなら異なるアプローチを考えなければなりませんが、6 割以上は完了しているようですので、 2 または 3 と考えるのが妥当な気がします。そこで、以下のように改良してみます。
- 破綻した番号については第 1 行から入れなおす。
- 無限ループに入らないように、繰り返し回数に上限を設ける。
この方針に基づいて作成したのが関数 sudoku() です。中身は概ね次のようになっています。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
sudoku() := ([a, p, d, q, n: 100,
M: zeromatrix(9, 9),
K: zeromatrix(9, 9),
T: zeromatrix(9, 9)],
for l: 1 while (l <= 9 and n >= 0) do (
n: n - 1,
q: 0,
for i: 1 while(i <= 9 and q = 0) do (
p: 0,
for j: 1 while (p = 0 and q = 0) do (
a: random(9) + 1,
if not member(0, K[i]) then (
q: 1,
l: l-1,
K: copymatrix(T),
M: copymatrix(T)
) else (
if K[i][a]=0 then (
p: 1,
for k: 1 thru 9 do (
d: f(f(i, a)[1], k),
K[d[1]][d[2]]: 1
),
for k: i thru 9 do K[k][a]: 1,
M[i][a]: l
)
)
)
),
K: copymatrix(M),
T: copymatrix(M)
),
if n < 0 then n else M
);
|
|
新変数 n が繰り返しの上限です。さしたる根拠もなく 100 にしてあります。入れる場所がなくなった場合に対する「やり直し処理」が
12 行から
17 行です。破綻せずにうまく完了した状態を新変数 T に保存しておき(
30 行と
31 行)、for ループ変数 l を一つ戻した上で(
14 行)K と M に書き戻しています(
15 行と
16 行)。