第3講 試行錯誤法でヒント数0数独の解答を作る(2)
第2話 81次順列を2次元に並べる
・
・
・
を実現するプログラム例
#include<iostream>
#include<conio.h> //while (!_kbhit()); を使うためのお呪い。
using namespace std;
void f(int s); //sは次元番号=部屋番号
int n; //次元数(部屋数)をキーボードから指定
int cn = 0; //順列を数える変数
int a[9][9];//大きめにとった
int main() {
//cout << "n = ";
//scanf_s("%d", &n); //キーボードからnの値を取得
n = 81;
f(0);
cout << "順列の場合の数は" << cn << "です。"
<< endl;
cout << "プロジェクト成功" << endl;
while (!_kbhit()); //待機させるための命令
return(0);
}
void f(int s) {
for (int i = 1; i < n + 1; i++) {
if (s == 0) {
a[s / 9][s % 9] = i;
}
if (s > 0) {
for (int j = 0; j < s; j++) {
if (i == a[j / 9][j % 9])goto tobi;
a[s / 9][s % 9] = i;
}
}
if (s + 1 < n)f(s + 1); //1つ上の次元に飛翔(1つ奥の部屋に入室)
if (cn == 100)return; //100個目の順列で止める
if (s + 1 == n) { //一番奥の部屋に到達!
cout << " ";
for (int j = 0; j < 13; j++)cout << " * ";
cout << endl;
for (int j = 0; j < 9; j++) { //順列を表示
cout << " ";
for (int k = 0; k < 9; k++) {
if (k % 3 == 0)cout << " * ";
if(a[j][k]<10)cout << " "<< a[j][k]
<< " "; else cout << a[j][k] << " ";
if (k == 8)cout << " * ";
}
if (j % 3 == 2) {
cout << endl<<" ";
for (int j = 0; j < 10; j++)cout << " * ";
}
cout << " ";
cout << endl;
}
cout << endl;
cn++; //順列数をカウント
if (cn == 100)return; //100個目の順列で止める
}
tobi:;
}
}
次にこの81次順列自動生成を改良して
①行だけ満たすものを疑似疑似数独を開発します。
・
・
・
一見同じことを繰り返しているように見えますが、
最下行から変更が始まり最終的に最上行まで変更が及び、
途中で止めなければすべての疑似疑似数独を生成させるプログラムとなっています。
尚、見栄えを考えて*を|または-に変更しました。
*|-はいずれもCVSファイルには反映されません。
なのでなくてもよいのですが、うまくいっているか確認のために入れた方がよいと思います。
エクセルシートに
初めから罫線によって枠組みを作っているので、
|または-を反映させる必要がないわけです。
第1話へ 第3話へ
トップへ