第16講 魔方陣汎用的生成プログラムへの挑戦
第8話 魔方陣汎用的自動生成プログラム解説その4
コード再掲
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 | ||
1 | |||
2 |
for(i=1;i<n*n+1;i++){
h=1;
m[y[g]][x[g]]=i;
よって、
0 | 1 | 2 | |
0 | 1 | 1 | |
1 | |||
2 |
となりますが、これは重複検査
for(j=0;j<g;j++){
if(m[y[g]][x[g]]==m[y[j]][x[j]]){
h=0;
}
}
によってチェックされてしまいます。
なぜなら現在f(1)の世界にいるわけですから、
g=1でfor文の1回目が実行され、
m[y[g]][x[g]]=m[y[1]][x[1]]=m[0][1]=1
m[y[j]][x[j]]=m[y[0]][x[0]]=1
でm[y[1]][x[1]]==m[y[0]][x[0]]が正しいからです。
したがいまして、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 | |
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[1]][x[1]]=m[0][1]=2
m[y[j]][x[j]]=m[y[0]][x[0]]=1
でm[y[g]][x[g]]==m[y[j]][x[j]]が成立しないからです。
そして、現在のセル
0 | 1 | 2 | |
0 | 1 | 2 | |
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(1)でg=1なので、if文の肯定側が実行されf(2)への世界へとワールドチェンジされるのです。
0 | 1 | 2 | |
0 | 1 | 2 | |
1 | |||
2 |
第7話へ 第9話へ
VB講義へ
VB講義基礎へ
vc++講義へ第1部へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)
初心者のための VC++による C言語 入門 C++ 入門
基礎から応用まで第1部
初心者のための VC++による C言語 入門 C++ 入門
基礎から応用まで第2部
初心者のための
VC++による C言語 入門 C++ 入門 基礎から応用まで第3部