第2講 試行錯誤法でヒント数0数独の解答を作る(1)
第12話 3次魔方陣自動生成
#include<iostream>
using namespace std;
void f(int s); //sは次元番号
int n; //次元数をキーボードから指定
int cn = 0; //順列を数える変数
int y[9] = { 0,1,2,0,2,0,1,1,2 };
int x[9] = { 0,1,2,2,0,1,0,2,1 };
int a[3][3];
int main() {
//cout << "n = ";
//scanf_s("%d", &n); //キーボードからnの値を取得
n = 9;
clock_t hj, ow;
hj = clock(); //始まりの時刻取得
f(0);
ow = clock(); //終わりの時刻取得
cout << "計算時間は" << (double)(ow - hj) / CLOCKS_PER_SEC
<< "秒です。" << endl;
cout << "魔方陣は" << cn << "個できました。"
<< endl;
cout << "プロジェクト成功" << endl;
return(0);
}
void f(int s) {
for (int i = 1; i < n + 1; i++) {
if (s == 0) {
a[y[s]][x[s]] = i;
}
if (s > 0) {
for (int j = 0; j < s; j++) {
if (i == a[y[j]][x[j]])goto tobi;
}
a[y[s]][x[s]] = i;
if (s == 2) {
int w = 0;
for (int j = 0; j < 3; j++)w += a[j][j];//右下がり対角線合計算出
if (w != 15)goto tobi;
}
if (s == 4) {
int w = 0;
for (int j = 0; j < 3; j++)w += a[j][2 - j];//右上がり対角線合計算出
if (w != 15)goto tobi;
}
if (s == 5) {
int w = 0;
for (int j = 0; j < 3; j++)w += a[0][j];//1行目合計算出
if (w != 15)goto tobi;
}
if (s == 6) {
int w = 0;
for (int j = 0; j < 3; j++)w += a[j][0];//1列目合計算出
if (w != 15)goto tobi;
}
if (s == 7) {
int w = 0;
for (int j = 0; j < 3; j++)w += a[1][j];//2行目合計算出
if (w != 15)goto tobi;
w = 0;
for (int j = 0; j < 3; j++)w += a[j][2];//3列目合計算出
if (w != 15)goto tobi;
}
if (s == 8) {
int w = 0;
for (int j = 0; j < 3; j++)w += a[2][j];//3行目合計算出
if (w != 15)goto tobi;
w = 0;
for (int j = 0; j < 3; j++)w += a[j][1];//2列目合憲算出
if (w != 15)goto tobi;
}
}
if (s + 1 < n)f(s + 1); //1つ上(奥)の次元に飛翔
if (s + 1 == n) { //一番奥の部屋に到達!
for (int j = 0; j < 3; j++) {//魔方陣をコンソールに出力
for (int k = 0; k < 3; k++) {
cout << a[j][k] << " ";
}
cout << endl;
}
cout << endl;
cn++; //順列数をカウント
}
tobi:;
}
}
------------------------------------------------
本講では、
では8つを区別していますが、
数学者たちが数独を研究するときは、
上の8つを1つとカウントします。
緑は赤を左右対称移動したものです。
上下対称移動や点対称移動などによって、
重なるものを1個と考えるわけです。
ですが、人間は左右対称移動した数独は別のものと認識しますので、
本講では8つを別のものとしてカウントします。
------------------------------------------------
ヒント数0の数独を解くには、まだまだやるべきことがたくさんあります。
第3講試行錯誤法でヒント数0数独の解答を作る(2)へ第1話への課題を出します。
行・列・ブロックの重複は気にしないで、
2次元配列には、1~9までの数字を入れて、
ブロックがわかるように
図のように*を入れてください。
生成させるものは10個という条件をいれます。
これを改良していって、
①行重複をしない ②列重複をしない ③ブロック重複をしない
と条件を加えて行ってヒント数0の数独を生成させます。
第11話へ 第3講第1話へ
トップへ