第16講 魔方陣汎用的生成プログラムへの挑戦
第9話 魔方陣汎用的自動生成プログラム解説その5
コード再掲
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 | 2 | |
1 | |||
2 |
for(i=1;i<n*n+1;i++){
h=1;
m[y[g]][x[g]]=i;
の1巡目において
0 | 1 | 2 | |
0 | 1 | 2 | 1 |
1 | |||
2 |
となりますがもちろんこれは重複検査をクリアできません。
理由は
for(j=0;j<g;j++){
if(m[y[g]][x[g]]==m[y[j]][x[j]]){
h=0;
}
}
の1回目のループにおいて
m[y[g]][x[g]]=m[y[2]][x[2]]=m[0][2]=1
m[y[j]][x[j]]=m[y[0]][x[0]]=1
なので等式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;
}
}
はすべてスルーされてしまい、
for(i=1;i<n*n+1;i++){
h=1;
m[y[g]][x[g]]=i;
の2巡目となり、
0 | 1 | 2 | |
0 | 1 | 2 | 2 |
1 | |||
2 |
となりますが、今度は重複試験の2度目のループにおいて
m[y[g]][x[g]]=m[y[2]][x[2]]=m[0][2]=2
m[y[j]][x[j]]=m[y[1]][x[1]]=2
ですから等式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;
}
}
が無視されてしまい、
for(i=1;i<n*n+1;i++){
h=1;
m[y[g]][x[g]]=i;
の3巡目ループから
0 | 1 | 2 | |
0 | 1 | 2 | 3 |
1 | |||
2 |
これは重複検査の2つのループをいずれもクリアします。
m[y[g]][x[g]]=m[y[2]][x[2]]=m[0][2]=3
m[y[j]][x[j]]=m[y[0]][x[0]]=1
m[y[g]][x[g]]=m[y[2]][x[2]]=m[0][2]=3
m[y[j]][x[j]]=m[y[1]][x[1]]=2
で等式m[y[g]][x[g]]==m[y[j]][x[j]]が成立しないからです。
ですから、h=0;は実行されずh=1;のままで、
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;
}
}
へと進みます。
セル(2,2)は該当セルなので、
0 | 1 | 2 | |
0 | 1 | 2 | 3 |
1 | |||
2 |
行(横)合計が計算されます。
ですが、合計は6で15には遙かに及ばず、if文if(w!=n*(n*n+1)/2)h=0;が実行され
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;
}
}
はすべて実行されず、
for(i=1;i<n*n+1;i++){
h=1;
m[y[g]][x[g]]=i;
4巡目ループで
0 | 1 | 2 | |
0 | 1 | 2 | 4 |
1 | |||
2 |
これも幸いにしまして、重複チェック
for(j=0;j<g;j++){
if(m[y[g]][x[g]]==m[y[j]][x[j]]){
h=0;
}
}
を通り抜けます。
m[y[g]][x[g]]=m[y[2]][x[2]]=m[0][2]=4
m[y[j]][x[j]]=m[y[0]][x[0]]=1
m[y[g]][x[g]]=m[y[2]][x[2]]=m[0][2]=4
m[y[j]][x[j]]=m[y[1]][x[1]]=2
で等式m[y[g]][x[g]]==m[y[j]][x[j]]2つとも成立しません。
それで再び
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;
}
}
へと進みますが、ここでも行(横)合計が計算されますが、
今回も合計は7で15ははるか彼方です。
まだまだ途は遠いわけです。
第8話へ 第10話へ
VB講義へ
VB講義基礎へ
vc++講義へ第1部へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)
初心者のための VC++による C言語 入門 C++ 入門
基礎から応用まで第1部
初心者のための VC++による C言語 入門 C++ 入門
基礎から応用まで第2部
初心者のための
VC++による C言語 入門 C++ 入門 基礎から応用まで第3部