第27講 数独(ナンプレ)自動生成
第6話 ブロックの条件を付け加えるには---その2
個別対応にならない汎用性=普遍性のあるプログラム
にするにはどうしたらよいでしょうか。
解決の方法は、
int f(int g,int m[10][10],int n,int* p,int* q,int cn){
int i,j,x,y;
x=p[g];
y=q[g];
for(i=1;i<=n;i++){
m[y][x]=i;
if(x>0)for(j=0;j<x;j++)if(m[y][x]==m[y][j])goto tobi;
if(y>0)for(j=0;j<y;j++)if(m[y][x]==m[j][x])goto tobi;
if(g+1<n*n){
cn=f(g+1,m,n,p,q,cn);
if(cn==100)return(cn);
}
else{
h(m,n);
cout<<endl<<endl;
if(cn==100)return(cn);
cn++;
}
tobi:;
}
return(cn);
}
のgを上手く利用することです。
gは
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
2 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
3 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
4 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
5 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 |
6 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
7 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 |
8 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 |
の白い大きな数字に対応します。
もし、・・・を2次元for文にするとしたら、
gとy座標およびx座標との関連づけをどうするかです。
実は、gからy座標とx座標を作り出すことは、
そんなに難しいことではありません。
そうです。
配列q[g]とp[g]がy座標とx座標にそれぞれ対応しています。
ですから、2次元for文にして
for(j=□;j<□+3;j++){
for(k=△;k<△+3;k++){
・・・・
}
}
□と△をp[g]とw[g]に関連づけることが出来て、
for文をどのタイミングでbreak; するかが解決できれば、
gを利用する方法による数独解答自動生成ソフトが完成することになります。
ヒントは、例えば
3 | 4 | 5 | |
0 | 3 | 4 | 5 |
1 | 12 | 13 | 14 |
2 | 21 | 22 | 23 |
q[22](=y)すなわち2から0をいかに作り出すか、
p[22](=x)すなわち4から3をいかに作り出すかです。
break; のタイミングについては、
逆にjとkから白い番号を作り出すことが出来れば、
あっさり解決します。
100個ではあっという間ですから、1万個に変更しました。