マルチスレッド版数独自動生成ソフトC++コードを題材とする超初心者のためのVisual Studio C++講義
第13章 様々な魔方陣の作成および自動生成
第6話 最初に1行にランダムに入れて2ずらしと3ずらしをして、2つの種の数字もランダムにずらす


1行目に並べる数字を種1においても種2においてもランダムに並べてください。

つまり、改良するのは

  for (size_t i = 0; i < n; i++) {

                for (size_t j = 0; j < n; j++) {

                        t1[i][j] = (j + 3 * i) % n;

                        t2[i][j] = (j + 2 * i) % n;

                }

        }
の部分です。1行目にランダムな数字を入れて種1は2つずらし種2は3つずらしを行うのです。

毎回結果を変えるために

size_t シード値 = (unsigned)time(NULL);

int main() {//私は社長だ。

              srand(シード値);


赤の2行を付け加えてください。

を実現するプログラム例

#include<iostream>//インクルードファイルiostreamの読み込み

#include<conio.h>//while(!_kbhit());を使うためのお呪い

#include<string> //文字列変数を使えるようにするために組み込む

#include <iomanip> //setprecisionを使えるように組み込む

#include <cmath>//powなどを使うときに必要

#include <ctime>//time()現時刻発生する関数)を使うために必要

using namespace std;//coutを使うときに必要なお呪い

void 魔方陣作成関数();

const size_t n = 5;

size_t mg = n * (n * n + 1) / 2;

size_t シード値 = (unsigned)time(NULL);

int main() {//私は社長だ。

        srand(シード値);

        魔方陣作成関数();

        cout << endl;

        cout << "プロジェクト終了" << endl;

        while (!_kbhit());//待機させるための命令

        return 0;//int main() を終わるためのお呪い

}

void 魔方陣作成関数() {

        size_t t1[n][n], t2[n][n];//魔方陣の種を収納する2次元配列

        size_t m[n][n];//5次魔方陣を収納する2次元配列

        cout << "種1" << endl;

        for (size_t i = 0; i < n; i++) {

                if (i == 0)t1[0][i] = rand() % n;

                if (i > 0) {

                        while (1) {

                                t1[0][i] = rand() % n;

                                size_t h = 1;

                                for (size_t j = 0; j < i; j++) {

                                        if (t1[0][i] == t1[0][j]) {

                                                h = 0;

                                                break;

                                        }

                                }

                                if (h == 1)break;

                        }

                }

        }     

        for (size_t i = 1; i < n; i++) {

                for (size_t j = 0; j < n; j++) {

                        t1[i][j] = t1[0][(j + 2 * i) % n];

                }

        }

        for (size_t i = 0; i < n; i++) {

                for (size_t j = 0; j < n; j++) {

                        cout << " " << t1[i][j] << "  ";

                }

                cout << endl;

        }

        cout << endl;

        cout << "種2" << endl;

        for (size_t i = 0; i < n; i++) {

                if (i == 0)t2[0][i] = rand() % n;

                if (i > 0) {

                        while (1) {

                                t2[0][i] = rand() % n;

                                size_t h = 1;

                                for (size_t j = 0; j < i; j++) {

                                        if (t2[0][i] == t2[0][j]) {

                                                h = 0;

                                                break;

                                        }

                                }

                                if (h == 1)break;

                        }

                }

        }

        for (size_t i = 1; i < n; i++) {

                for (size_t j = 0; j < n; j++) {

                        t2[i][j] = t2[0][(j + 3 * i) % n];

                }

        }

        for (size_t i = 0; i < n; i++) {

                for (size_t j = 0; j < n; j++) {

                        cout << " " << t2[i][j] << "  ";

                }

                cout << endl;

        }

        //5次魔方陣作成

        for (size_t i = 0; i < n; i++) {

                for (size_t j = 0; j < n; j++) {

                        m[i][j] = n * t1[i][j] + t2[i][j] + 1;

                }

        }

        //5次魔方陣表示

        cout << endl;

        cout << "魔方陣表示" << endl;

        for (size_t i = 0; i < n; i++) {

                for (size_t j = 0; j < n; j++) {

                        if (m[i][j] < 10) {

                                cout << " " << m[i][j] << "  ";

                        }

                        else {

                                cout << m[i][j] << "  ";

                        }

                }

                cout << endl;

        }

        size_t c = 1;

        for (size_t i = 0; i < n; i++) {

                size_t gk = 0;

                for (size_t j = 0; j < n; j++) {

                        gk += m[(j + i) % n][j];

                }

                if (gk != mg) {

                        c = 0;

                        break;

                }

        }

        if (c == 1) {

                for (size_t i = 0; i < n; i++) {

                        size_t gk = 0;

                        for (size_t j = 0; j < n; j++) {

                                gk += m[(j + n - i) % n][n - 1 - j];

                        }

                        if (gk != mg) {

                                c = 0;

                                break;

                        }

                }

        }

        if (c == 1) {

                for (size_t i = 0; i < n; i++) {

                        size_t gk = 0;

                        for (size_t j = 0; j < n; j++) {

                                gk += m[i][j];

                        }

                        if (gk != mg) {

                                c = 0;

                                break;

                        }

                }

        }

        if (c == 1) {

                for (size_t i = 0; i < n; i++) {

                        size_t gk = 0;

                        for (size_t j = 0; j < n; j++) {

                                gk += m[j][i];

                        }

                        if (gk != mg) {

                                c = 0;

                                break;

                        }

                }

        }

        if (c == 1)cout << "完全魔方陣です。" << endl; else cout << "完全魔方陣ではありません。" << endl;

        cout << endl;

        size_t a = rand() % n;

        for (size_t i = 0; i < n; i++) {

                for (size_t j = 0; j < n; j++) {

                        t1[i][j] = (t1[i][j] + a) % n;

                }

        }

        for (size_t i = 0; i < n; i++) {

                for (size_t j = 0; j < n; j++) {

                        m[i][j] = n * t1[i][j] + t2[i][j] + 1;

                }

        }

        cout << "数字をずらした種1と方陣表示" << endl;

        for (size_t i = 0; i < n; i++) {

                for (size_t j = 0; j < n; j++) {

                        cout << " " << t1[i][j] << "  ";

                }

                cout << endl;

        }

        cout << endl;

        for (size_t i = 0; i < n; i++) {

                for (size_t j = 0; j < n; j++) {

                        if (m[i][j] < 10) {

                                cout << " " << m[i][j] << "  ";

                        }

                        else {

                                cout << m[i][j] << "  ";

                        }

                }

                cout << endl;

        }

        c = 1;

        for (size_t i = 0; i < n; i++) {

                size_t gk = 0;

                for (size_t j = 0; j < n; j++) {

                        gk += m[(j + i) % n][j];

                }

                if (gk != mg) {

                        c = 0;

                        break;

                }

        }

        if (c == 1) {

                for (size_t i = 0; i < n; i++) {

                        size_t gk = 0;

                        for (size_t j = 0; j < n; j++) {

                                gk += m[(j + n - i) % n][n - 1 - j];

                        }

                        if (gk != mg) {

                                c = 0;

                                break;

                        }

                }

        }

        if (c == 1) {

                for (size_t i = 0; i < n; i++) {

                        size_t gk = 0;

                        for (size_t j = 0; j < n; j++) {

                                gk += m[i][j];

                        }

                        if (gk != mg) {

                                c = 0;

                                break;

                        }

                }

        }

        if (c == 1) {

                for (size_t i = 0; i < n; i++) {

                        size_t gk = 0;

                        for (size_t j = 0; j < n; j++) {

                                gk += m[j][i];

                        }

                        if (gk != mg) {

                                c = 0;

                                break;

                        }

                }

        }

        if (c == 1)cout << "完全魔方陣です。" << endl; else cout << "完全魔方陣ではありません。" << endl;

        cout << endl;

        size_t b = rand() % n;

        for (size_t i = 0; i < n; i++) {

                for (size_t j = 0; j < n; j++) {

                        t2[i][j] = (t2[i][j] + b) % n;

                }

        }

        for (size_t i = 0; i < n; i++) {

                for (size_t j = 0; j < n; j++) {

                        m[i][j] = n * t1[i][j] + t2[i][j] + 1;

                }

        }

        cout << "数字をずらした種2と方陣表示" << endl;

        for (size_t i = 0; i < n; i++) {

                for (size_t j = 0; j < n; j++) {

                        cout << " " << t2[i][j] << "  ";

                }

                cout << endl;

        }

        cout << endl;

        for (size_t i = 0; i < n; i++) {

                for (size_t j = 0; j < n; j++) {

                        if (m[i][j] < 10) {

                                cout << " " << m[i][j] << "  ";

                        }

                        else {

                                cout << m[i][j] << "  ";

                        }

                }

                cout << endl;

        }

        c = 1;

        for (size_t i = 0; i < n; i++) {

                size_t gk = 0;

                for (size_t j = 0; j < n; j++) {

                        gk += m[(j + i) % n][j];

                }

                if (gk != mg) {

                        c = 0;

                        break;

                }

        }

        if (c == 1) {

                for (size_t i = 0; i < n; i++) {

                        size_t gk = 0;

                        for (size_t j = 0; j < n; j++) {

                                gk += m[(j + n - i) % n][n - 1 - j];

                        }

                        if (gk != mg) {

                                c = 0;

                                break;

                        }

                }

        }

        if (c == 1) {

                for (size_t i = 0; i < n; i++) {

                        size_t gk = 0;

                        for (size_t j = 0; j < n; j++) {

                                gk += m[i][j];

                        }

                        if (gk != mg) {

                                c = 0;

                                break;

                        }

                }

        }

        if (c == 1) {

                for (size_t i = 0; i < n; i++) {

                        size_t gk = 0;

                        for (size_t j = 0; j < n; j++) {

                                gk += m[j][i];

                        }

                        if (gk != mg) {

                                c = 0;

                                break;

                        }

                }

        }

        if (c == 1)cout << "完全魔方陣です。" << endl; else cout << "完全魔方陣ではありません。" << endl;

        cout << "以上の結果は種1については" << a << "ずらし、種2については" << b << "ずらした場合です。" << endl;

}

前回に素数次魔方陣の最後の課題と言ってしまいましたが、

もう一つだけ加えることをお許しください。

今回のコードを改良して7次の完全魔方陣を作成してください。



第1話の謎にまだ答えていませんが、第7話でお答えします。

第8話では魔方陣の種について解説します。






第13章第5話へ 第13章7話へ

本講義トップへ