マルチスレッド版数独自動生成ソフトC++コードを題材とする超初心者のためのVisual Studio C++講義
第13章 様々な魔方陣の作成および自動生成
第13話 1行数独の構造解析

1行数独の構造解析

を実現するコード例
#pragma warning(disable: 4996)//第2編のために必要
#include<iostream>//インクルードファイルiostreamの読み込み
#include<conio.h>//while(!_kbhit());を使うためのお呪い
#include<string> //文字列変数を使えるようにするために組み込む
#include <iomanip> //setprecisionを使えるように組み込む
#include <cmath>//powなどを使うときに必要
#include <ctime>//time()(←現時刻発生する関数)を使うために必要
using namespace std;//coutを使うときに必要なお呪い
#include <process.h>//_beginthreadを使うために必要
void 全体構造解析関数();//スレッドを派生させる関数
const int n = 9;//数独の一辺は9です
int s[n][n][n];//各空欄の候補数字を収納する3次元配列
int a[n][n];//問題及び解答を収納する2次元配列
int mx[n][n];//各空欄の候補数字数
int main() {
//すべてを0に初期化
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
a[i][j] = 0;
}
}
//候補数字数を9で初期化
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
mx[i][j] = 9;
}
}
//データ入力
a[0][0] = 2;
a[0][4] = 8;
a[0][8] = 9;
全体構造解析関数();
//各空欄候補数字表
for (int i = 0; i < n; i++) {
if (a[0][i] == 0) {
for (int j = 0; j < mx[0][j]; j++) {
cout << "s[0][" << i << "][" << j << "] = " << s[0][i][j] << endl;
}
}
cout << endl;
}
while (!_kbhit());//待機させるための命令
return(0);
}
void 全体構造解析関数() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (a[i][j] == 0) {
for (int k = 0; k < n; k++) {
s[i][j][k] = k + 1;//空欄のすべてに1~9までをリストする
}
}
}
}
for (int i = 0; i < n; i++) {
if (a[0][i] == 0) {
for (int j = 0; j < n; j++) {
if (a[0][j] > 0) {
int k = 0;
while (k < mx[0][i]) {
if (s[0][i][k] == a[0][j]) {
mx[0][i]--;
s[0][i][k] = s[0][i][mx[0][i]];
}
else {
k++;
}
}
}
}
}
}
}
むずかしかったでしょう。
ですから、わからずに答を見てしまった人は沢山いますからご心配はいりません。
私でさえ少し苦戦したのですから。
答を見ずに実現できた方は大いに自信を持ってください。
初心者でこのコード組めたことは誇りに思ってよい結果です。
今回の結果全部同じになっていますが、

1行数独ですから全く正しい結果です。
結果が出力されたときに必ず正しいかどうか、確認作業をしてください。
1行数独と結果を交互に見て正しいか確認する作業です。
さて、次の課題です。
1列数独の構造解析に挑戦です。
今のコードは残しておいてコードを加えましょう。
今回はノーヒントです。
でも、横が縦になるだけでも結構難しいですよ。
ですが、今回の1行数独を参考に組んでください。
実行結果は今回もすべて同じになります。
今回と同じという意味ではなくて、列についての構造解析の結果がすべて同じになるという意味です。
第13章第12話へ 第13章14話へ
本講義トップへ