マルチスレッド版数独自動生成ソフトC++コードを題材とする超初心者のためのVisual Studio C++講義
第10章 関数の再帰的使用によって魔方陣を自動生成する
第8話 仮屋崎さんの天才的方法解説の解説その3=第2の要点
プログラムコード再掲
void 2次座標生成() {//y横座標とx縦座標生成
int i, j, c;
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
a[i][j] = -1;
}
}
for (i = 0; i < n; i++) {
a[i][i] = i;
}
c = n - 1;
for (i = 0; i < n; i++) {
if (a[i][n - 1 - i] == -1) {
c++;
a[i][n - 1 - i] = c;
}
}
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
x[a[i][j]] = j;
y[a[i][j]] = i;
}
}
}

以下の解説を読むときに中学校や高校の数学で学んだ座標は(x, y)の順に並んでいますが、
プログラミングでは(y, x)の順に並んでいることに注意が必要です。
数学では(横座標、縦座標)となっていますが、エクセルやプログラミングの世界では(縦座標、横座標)の順に並んでいます。
しかも、縦座標は下向きです。数学では上向きですから逆向きです。
理由は配列がa[縦座標][横座標]の順に並んでいるからです。
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
x[a[i][j]] = j;
y[a[i][j]] = i;
}
}
この一つの方式で場合分けしたらとてつもなく複雑になるものがすっきり部屋番号とy座標とx座標が関連付けられるのです。
for (i = 0; i < n; i++) {
a[i][i] = i;
}
c = n - 1;
for (i = 0; i < n; i++) {
if (a[i][n - 1 - i] == -1) {
c++;
a[i][n - 1 - i] = c;
}
}
部屋番号づけのときのy座標とx座標を逆利用すれば、
確かに解決します。
x[a[i][j]] = j;
y[a[i][j]] = i;
は答を内蔵しています。

a[0][0]のy座業は0ですし、x座標は0です
a[2][1]のy座業は2ですし、x座標は1です。
a[3][4]のy座業は3ですし、x座標は4です。
a[1][3]のy座業は1ですし、x座標は3です。
一般化して
a[p][q]のy座業はpですし、x座標はqです。
そうです。
答が内蔵されているといった意味がお分かりなるのではないでしょうか。
ですから
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
x[a[i][j]] = j;
y[a[i][j]] = i;
}
}
y座標とx座標が完成してしまうのです。
仮屋崎さんって本当に天才ですね!
では、皆さん本章究極の課題です。
普遍的な魔方陣自動生成ソフトを完成させましょう。
具体的な数字で表すのではなくy[s]とx[s]とnを使ってコーティングしてください。
合計処理もfor文を使います。

(
・
1 23 21 17 3
22 2 15 14 12
18 10 13 4 20
8 19 9 24 5
16 11 7 6 25
1 22 23 16 3
21 2 17 14 11
18 9 13 6 19
10 20 4 24 7
15 12 8 5 25
1 22 23 16 3
21 2 17 15 10
11 18 13 4 19
12 14 7 24 8
20 9 5 6 25
1 23 22 16 3
11 2 18 15 19
21 17 13 4 10
12 14 7 24 8
20 9 5 6 25
1 23 22 16 3
11 2 18 15 19
21 17 13 6 8
12 14 5 24 10
20 9 7 4 25
1 23 22 16 3
18 2 11 15 19
21 17 13 6 8
5 14 12 24 10
20 9 7 4 25
1 23 21 17 3
19 2 9 15 20
22 14 13 5 11
7 18 10 24 6
16 8 12 4 25
1 23 21 17 3
20 2 9 15 19
22 14 13 5 11
6 18 10 24 7
16 8 12 4 25
・
)