第16講 魔方陣汎用的生成プログラムへの挑戦
第11話 魔方陣汎用的自動生成プログラム解説その7
コード再掲
f(0);
}
public static void f(int g){
if(cn>20)return;
int i,j,k,h;
for(i=1;i<n*n+1;i++){
h=1;
m[y[g]][x[g]]=i;
for(j=0;j<g;j++){
if(m[y[g]][x[g]]==m[y[j]][x[j]]){
h=0;
}
}
for(j=0;j<g;j++){
if(m[y[g]][x[g]]==m[y[j]][x[j]]){
h=0;
}
}
if(h==1){
if(x[g]==n-1){
w=0;
for(j=0;j<n;j++){
w+=m[y[g]][j];
}
if(w!=n*(n*n+1)/2)h=0;
}
}
if(h==1){
if(y[g]==n-1){
w=0;
for(j=0;j<n;j++){
w+=m[j][x[g]];
}
if(w!=n*(n*n+1)/2)h=0;
}
}
if(h==1){
if(y[g]==n-1 && x[g]==0){
w=0;
for(j=0;j<n;j++){
w+=m[j][n-1-j];
}
if(w!=n*(n*n+1)/2)h=0;
}
}
if(h==1){
if(y[g]==n-1 && x[g]==n-1){
w=0;
for(j=0;j<n;j++){
w+=m[j][j];
}
if(w!=n*(n*n+1)/2)h=0;
}
}
if(h==1){
if(g+1<n*n){
f(g+1);
if(cn>20)return;
}
else{
cn++;
for(j=0;j<n;j++){
for(k=0;k<n;k++){
if(m[j][k]<10){
System.out.print(" "+m[j][k]+" ");
}
else{
System.out.print(m[j][k]+" ");
}
}
System.out.println();
}
System.out.println();
if(cn>20)return;
}
}
}
}
}
0 | 1 | 2 | |
0 | 1 | 3 | |
1 | |||
2 |
以下
0 | 1 | 2 | |
0 | 1 | 4 | |
1 | |||
2 |
0 | 1 | 2 | |
0 | 1 | 4 | 1 |
1 | |||
2 |
0 | 1 | 2 | |
0 | 1 | 4 | 2 |
1 | |||
2 |
0 | 1 | 2 | |
0 | 1 | 4 | 3 |
1 | |||
2 |
0 | 1 | 2 | |
0 | 1 | 4 | 4 |
1 | |||
2 |
0 | 1 | 2 | |
0 | 1 | 4 | 5 |
1 | |||
2 |
0 | 1 | 2 | |
0 | 1 | 4 | 6 |
1 | |||
2 |
0 | 1 | 2 | |
0 | 1 | 4 | 7 |
1 | |||
2 |
0 | 1 | 2 | |
0 | 1 | 4 | 8 |
1 | |||
2 |
0 | 1 | 2 | |
0 | 1 | 4 | 9 |
1 | |||
2 |
のいずれも重複検査または横合計検査をクリアできません。
しかし、最後は合計14となり後一歩です。
以下
0 | 1 | 2 | |
0 | 1 | 5 | |
1 | |||
2 |
0 | 1 | 2 | |
0 | 1 | 5 | 1 |
1 | |||
2 |
0 | 1 | 2 | |
0 | 1 | 5 | 2 |
1 | |||
2 |
0 | 1 | 2 | |
0 | 1 | 5 | 3 |
1 | |||
2 |
0 | 1 | 2 | |
0 | 1 | 5 | 4 |
1 | |||
2 |
0 | 1 | 2 | |
0 | 1 | 5 | 5 |
1 | |||
2 |
0 | 1 | 2 | |
0 | 1 | 5 | 6 |
1 | |||
2 |
0 | 1 | 2 | |
0 | 1 | 5 | 7 |
1 | |||
2 |
0 | 1 | 2 | |
0 | 1 | 5 | 8 |
1 | |||
2 |
0 | 1 | 2 | |
0 | 1 | 5 | 9 |
1 | |||
2 |
とここまで来てようやく横合計検査の難関を突破するのです。
if(h==1){
if(y[g]==n-1){
w=0;
for(j=0;j<n;j++){
w+=m[j][x[g]];
}
if(w!=n*(n*n+1)/2)h=0;
}
}
if(h==1){
if(y[g]==n-1 && x[g]==0){
w=0;
for(j=0;j<n;j++){
w+=m[j][n-1-j];
}
if(w!=n*(n*n+1)/2)h=0;
}
}
if(h==1){
if(y[g]==n-1 && x[g]==n-1){
w=0;
for(j=0;j<n;j++){
w+=m[j][j];
}
if(w!=n*(n*n+1)/2)h=0;
}
}
のいずれも該当せず、久しぶりに
if(h==1){
if(g+1<n*n){
f(g+1);
if(cn>20)return;
}
else{
cn++;
for(j=0;j<n;j++){
for(k=0;k<n;k++){
if(m[j][k]<10){
System.out.print(" "+m[j][k]+" ");
}
else{
System.out.print(m[j][k]+" ");
}
}
System.out.println();
}
System.out.println();
if(cn>20)return;
}
}
まだf(2)でg=2なので、肯定側の命令が遂行され、f(3)の世界=外側から4番目の人形へと次元移動がなされれます。
0 | 1 | 2 | |
0 | 1 | 5 | 9 |
1 | |||
2 |
以下
0 | 1 | 2 | |
0 | 1 | 5 | 9 |
1 | 1 | ||
2 |
0 | 1 | 2 | |
0 | 1 | 5 | 9 |
1 | 2 | ||
2 |
0 | 1 | 2 | |
0 | 1 | 5 | 9 |
1 | 2 | ||
2 |
0 | 1 | 2 | |
0 | 1 | 5 | 9 |
1 | 2 | 1 | |
2 |
0 | 1 | 2 | |
0 | 1 | 5 | 9 |
1 | 2 | 2 | |
2 |
1
0 | 1 | 2 | |
0 | 1 | 5 | 9 |
1 | 2 | 3 | |
2 |
0 | 1 | 2 | |
0 | 1 | 5 | 9 |
1 | 2 | 3 | |
2 |
0 | 1 | 2 | |
0 | 1 | 5 | 9 |
1 | 2 | 3 | 1 |
2 |
0 | 1 | 2 | |
0 | 1 | 5 | 9 |
1 | 2 | 3 | 2 |
2 |
0 | 1 | 2 | |
0 | 1 | 5 | 9 |
1 | 2 | 3 | 3 |
2 |
1
と重複チェック及び2行目の行合計検査との戦いが、延々と繰り返されていきます。
途は遠く、途半ばにも達していないことがわかります。
9次順列は、9!=362880通りもあり、その内魔方陣の条件を満たすものは8通りしかないのですから、
厳しい戦いであるのは当然なのです。
第10話へ 第12話へ
VB講義へ
VB講義基礎へ
vc++講義へ第1部へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)
初心者のための VC++による C言語 入門 C++ 入門
基礎から応用まで第1部
初心者のための VC++による C言語 入門 C++ 入門
基礎から応用まで第2部
初心者のための
VC++による C言語 入門 C++ 入門 基礎から応用まで第3部