第19講 座標の工夫による魔方陣自動生成ソフトの高速化
第7話 コード解説その2
if(s==n-1 && t==n-1){
w=0;
for(j=0;j<n;j++)w=w+x[j][j];
if(w!=n*(n*n+1)/2)goto tobi;
}
if(s==n-1 && t==0){
w=0;
for(j=0;j<n;j++)w=w+x[j][n-1-j];
if(w!=n*(n*n+1)/2)goto tobi;
}
if(s==0 && t==n-2){
w=0;
for(j=0;j<n;j++)w+=x[s][j];
if(w!=n*(n*n+1)/2)goto tobi;
}
if(s==n-2 && t==0){
w=0;
for(j=0;j<n;j++)w+=x[j][t];
if(w!=n*(n*n+1)/2)goto tobi;
}
if(s>0 && s<n-1 && t==n-1){
w=0;
for(j=0;j<n;j++)w+=x[s][j];
if(w!=n*(n*n+1)/2)goto tobi;
}
if(s==n-1 && t>0 && t<n-1){
w=0;
for(j=0;j<n;j++)w+=x[j][t];
if(w!=n*(n*n+1)/2)goto tobi;
}
の解説の続き
0 | 1 | 2 | 3 | |
0 | 0 | 8 | 9 | 4 |
1 | 10 | 1 | 5 | 11 |
2 | 12 | 6 | 2 | 13 |
3 | 7 | 14 | 15 | 3 |
0 | 1 | 2 | 3 | 4 | |
0 | 0 | 9 | 10 | 11 | 5 |
1 | 12 | 1 | 13 | 6 | 14 |
2 | 15 | 16 | 2 | 17 | 18 |
3 | 19 | 7 | 20 | 3 | 21 |
4 | 8 | 22 | 23 | 24 | 4 |
x[n-2][0]が埋まった時点で、1列目のすべての数字が埋まるので、
if(s==n-2 && t==0){
w=0;
for(j=0;j<n;j++)w+=x[j][t];
if(w!=n*(n*n+1)/2)goto tobi;
}
は当然ということになります。
n=4のときすなわち4次魔方陣のとき、n-2は2ですから、
s==n-2 && t==0はs=2 && t==0
となり、
12 |
のセルを示しますし、
n=5のときすなわち5次魔方陣のとき、n-2は3ですから、
s==n-2 && t==0はs==3 && t==0
となり、
19 |
のセルの場合になるわけです。
ですから、
w=0;
for(j=0;j<n;j++)w+=x[j][t];
if(w!=n*(n*n+1)/2)goto tobi;
によって、1列目の合計がn*(n*n+1)/2になっているかどうかを確認して、
魔方陣の条件を満たしているかどうかをテストしているわけです。
0 | 1 | 2 | 3 | |
0 | 0 | 8 | 9 | 4 |
1 | 10 | 1 | 5 | 11 |
2 | 12 | 6 | 2 | 13 |
3 | 7 | 14 | 15 | 3 |
0 | 1 | 2 | 3 | 4 | |
0 | 0 | 9 | 10 | 11 | 5 |
1 | 12 | 1 | 13 | 6 | 14 |
2 | 15 | 16 | 2 | 17 | 18 |
3 | 19 | 7 | 20 | 3 | 21 |
4 | 8 | 22 | 23 | 24 | 4 |
次には、青色のセルが埋まった時点でそれぞれの行の
すべてが埋まりますから、各行の検査
if(s>0 && s<n-1 && t==n-1){
w=0;
for(j=0;j<n;j++)w+=x[s][j];
if(w!=n*(n*n+1)/2)goto tobi;
}
が実施されるのは当然です。
s>0 && s<n-1となっているのは、上の図をご覧になればお分かりですよね。
n=4のときすなわり4次魔方陣のとき、
s>0 && s<n-1はs>0 && s<3 となりますから1行目と2行目ということですし、
n=5のときすなわり5次魔方陣のとき、
s>0 && s<n-1はs>0 && s<4 となりますから1行目から3行目までということになるからです。
そして、最後に
0 | 1 | 2 | 3 | |
0 | 0 | 8 | 9 | 4 |
1 | 10 | 1 | 5 | 11 |
2 | 12 | 6 | 2 | 13 |
3 | 7 | 14 | 15 | 3 |
0 | 1 | 2 | 3 | 4 | |
0 | 0 | 9 | 10 | 11 | 5 |
1 | 12 | 1 | 13 | 6 | 14 |
2 | 15 | 16 | 2 | 17 | 18 |
3 | 19 | 7 | 20 | 3 | 21 |
4 | 8 | 22 | 23 | 24 | 4 |
青色のセルが埋まれば、対応する各列のすべての数字が埋まりますから、
各列の列合計が条件を満たすか、
if(s==n-1 && t>0 && t<n-1){
w=0;
for(j=0;j<n;j++)w+=x[j][t];
if(w!=n*(n*n+1)/2)goto tobi;
}
テストするのは当然です。
n=4のときすなわり4次魔方陣のとき、
t>0 && t<n-1はt>0 && t<3 となりますから1列目と2列目ということですし、
n=5のときすなわり5次魔方陣のとき、
t>0 && t<n-1はt>0 && t<4 となりますから1列目から3列目までですね。
数字を入れる順番を変えただけで、
6次魔方陣では、
おそらく、1億倍ぐらい速くなりますが、
それでも、6次魔方陣では歯が立ちません。
ですが、今のコードを基本的にはいじらずちょっと工夫するだけで、
100個程度なら、数秒から数分程度で、
6次どころが11次ぐらいまで生産が可能になります。
何をするかと申しますと、
乱数を入れるということです。