第10講 関数の再帰的使用による魔方陣の自動生成
第8話 4次魔方陣の全生成を可能にするコード例
#include<iostream> //入出力のために組み込む
#include<ctime> //時間を計測するために必要
using namespace std; //coutを使うために必要なお呪い
void f(int g);
int mah[5][5];
int n, cn;
int main() {
  clock_t hj, ow;
  cout << "これはすべてのn次魔方陣を求めるソフトです。" << endl;
  cout << "何のn次魔方陣を発生させるのかをnに入力してエンターして下さい。" << endl;
  cout << "n=";
  scanf("%d", &n);
  cn = 0;
  hj = clock();
  f(0);
  ow = clock();
  cout << "魔方陣生成にかかった時間は" << (double)(ow - hj) / 1000 << "秒です。";
  cout << "生成された" << n << "次魔方陣" << cn << "個です。" << endl;
  return(0);
}
void f(int g) {
  int i, j, k, h, w, x, y;
  y = g / n;
  x = g % n;
  for (i = 0; i<n*n; i++) {
    if (g == 0)mah[y][x] = i + 1;
    h = 1;
    if (g>0) {
      for (j = 0; j<g; j++) {
        if (mah[j / n][j%n] == i + 1) {
          h = 0;
          break;
        }
      }
      if (h == 1)mah[y][x] = i + 1;
    }
    if (x == n - 1) {
      w = 0;
      for (j = 0; j<n; j++)w += mah[y][j];
      if (w != n*(n*n + 1) / 2)h = 0;
    }
    if (h == 1) {
      if (y == n - 1) {
        w = 0;
        for (j = 0; j<n; j++)w += mah[j][x];
        if (w != n*(n*n + 1) / 2)h = 0;
      }
    }
    if (h == 1) {
      if (y == n - 1 && x == 0) {
        w = 0;
        for (j = 0; j<n; j++)w += mah[j][n - 1 - j];
        if (w != n*(n*n + 1) / 2)h = 0;
      }
    }
    if (h == 1) {
      if (x == n - 1 && y == n - 1) {
        w = 0;
        for (j = 0; j<n; j++)w += mah[j][j];
        if (w != n*(n*n + 1) / 2)h = 0;
      }
    }
    if (h == 1) {
      if (g + 1 < n*n) {
        f(g + 1);
      }
      else {
        for (j = 0; j < n; j++) {
          for (k = 0; k < n; k++) {
            if(mah[j][k]<10)cout<< " " << mah[j][k] << " "; //2桁への対応
            if(mah[j][k]>=10)cout<< mah[j][k] << " "; //2桁への対応
          }
          cout << endl;
        }
        cout << endl;
        cn++;
      }
    }
  }
}
実行画面
これはすべてのn次魔方陣を求めるソフトです。
何のn次魔方陣を発生させるのかをnに入力してエンターして下さい。
n=3
2 7 6
9 5 1
4 3 8

2 9 4
7 5 3
6 1 8

4 3 8
9 5 1
2 7 6

4 9 2
3 5 7
8 1 6

6 1 8
7 5 3
2 9 4

6 7 2
1 5 9
8 3 4

8 1 6
3 5 7
4 9 2

8 3 4
1 5 9
6 7 2

魔方陣生成にかかった時間は0.001秒です。生成された3次魔方陣8個です。


1次元配列を利用していた場合の実行結果が、
数独(ナンプレ)生成にかかった時間は0.109000秒です。
ですから3次魔方陣の場合は1090倍ですが、
4次魔方陣では倍速効果はもっと大きくなります。
前話で5000倍程度と書きましたが、
実験すると1万倍を超えると思います。
その結果、
4次魔方陣7040個の全生成が11分で可能になりました。
このソフトを魔方陣自動生成Ver.1と名付けることにしましょう。
バージョンは講義の進展と共に上がっていきます。
1つバージョンアップするだけで、数十倍から数万倍のスピードアップがされていきます。

以上をもちまして第10講を閉めると同時に、
Visual Studio Community 2017によるC++入門第1部を終了します。
長らくのご聴講ありがとうございました。
講義はまだまだ続きます。
そして、第3部辺りでゲームプログラミングにも挑戦します。



第7話へ   第11講第1話へ

002

初心者のための excel 2016 マクロ VBA 入門講義 基礎から応用まで
vc** c言語 c** 入門 初心者 基礎から応用まで
eclipse c** 入門
魔方陣 数独で学ぶ VBA 入門

数独のシンプルな解き方・簡単な解法の研究
VB講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C**入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)
初心者のための VC**による C言語 C++ 入門 基礎から応用まで第1部
eclipse java 入門
java 入門 サイト 基礎から応用まで
本サイトトップへ