第8講 for文・if文・配列・ポインタを総動員して3次魔方陣の自動生成に挑戦する!
第1話 3次魔方陣を作るには?
魔方陣については、
前に説明したことがあります。
第6講第8話で触れています。
8 | 1 | 6 |
3 | 5 | 7 |
4 | 9 | 2 |
1 | 6 | 11 | 16 |
15 | 12 | 5 | 2 |
8 | 3 | 14 | 9 |
10 | 13 | 4 | 7 |
1 | 7 | 13 | 19 | 25 |
18 | 24 | 5 | 6 | 12 |
10 | 11 | 17 | 23 | 4 |
22 | 3 | 9 | 15 | 16 |
14 | 20 | 21 | 2 | 8 |
7 | 23 | 37 | 64 | 33 | 57 | 25 | 14 |
3 | 55 | 44 | 18 | 50 | 6 | 21 | 63 |
61 | 27 | 30 | 26 | 60 | 1 | 31 | 24 |
46 | 36 | 12 | 17 | 15 | 38 | 34 | 62 |
19 | 51 | 22 | 53 | 28 | 16 | 29 | 42 |
35 | 9 | 59 | 20 | 56 | 39 | 32 | 10 |
40 | 48 | 4 | 54 | 13 | 58 | 41 | 2 |
49 | 11 | 52 | 8 | 5 | 45 | 47 | 43 |
などが魔方陣です。
各行(横列)・各列(縦列)・対角線の合計が
すべて同じになるものです。
3次魔方陣は、全部で
2 | 9 | 4 |
7 | 5 | 3 |
6 | 1 | 8 |
2 | 7 | 6 |
9 | 5 | 1 |
4 | 3 | 8 |
4 | 9 | 2 |
3 | 5 | 7 |
8 | 1 | 6 |
4 | 3 | 8 |
9 | 5 | 1 |
2 | 7 | 6 |
6 | 7 | 2 |
1 | 5 | 9 |
8 | 3 | 4 |
6 | 1 | 8 |
7 | 5 | 3 |
2 | 9 | 4 |
8 | 3 | 4 |
1 | 5 | 9 |
6 | 7 | 2 |
8 | 1 | 6 |
3 | 5 | 7 |
4 | 9 | 2 |
と全部で8個の解答しかもっていないことを
プログラムを組んで証明するのです。
最もよくご覧になればお分かりのように、
上の8個は対称移動や鏡像移動などで重なるものばかりですので、
本質的には1個の解ですが、
本サイトでは鏡像なども別の解として扱います。
すべての場合を調べて、
8個しか解答が存在しないことを
証明するにはどうしたらよいでしょうか。
1 | 2 | 3 |
4 | 5 | 6 |
7 | 8 | 9 |
1 | 2 | 3 |
4 | 5 | 6 |
7 | 9 | 8 |
1 | 2 | 3 |
4 | 5 | 6 |
8 | 7 | 9 |
1 | 2 | 3 |
4 | 5 | 6 |
8 | 9 | 7 |
1 | 2 | 3 |
4 | 5 | 6 |
9 | 7 | 8 |
1 | 2 | 3 |
4 | 5 | 6 |
9 | 8 | 7 |
1 | 2 | 3 |
4 | 5 | 7 |
6 | 8 | 9 |
1 | 2 | 3 |
4 | 5 | 7 |
6 | 9 | 8 |
・・・
などすべての場合を作って、
この中で各行・各列・各対角線の合計がすべて15になっているものを
探し出せばよいのです。
上の表は、順列
123456789
123456798
123456879
123456897
123456978
123456987
123457689
・
・
・
を2次元に並び直したものです。
ですから、すべての順列を作り出すプログラムを
考え出せれば、後はif文を使い、
魔方陣の条件を満たしているものを選らび出せばよいのです。
いきなり、9個の順列では難しいですから、
3個の順列
123
132
213
231
312
321
を作り出すにはどうしたらよいか考えましょう。
そのために
x[0] | x[1] | x[2] |
3つのスペースを用意します。
1番目の枠に入る可能性がある数字は、
1から3です。
これはfor文で実現できます。
2番目・3番目の枠も同じです。
ただし、2番目と3番目については条件がつきます。
2番目は、
1番目と異なる数字を入れなければならない、すなわちx[1]≠x[0]
3番目は、
1番目と2番目の両方と異なる数字を入れなければならない、すなわちx[2]≠x[0]かつx[2]≠x[1]
3次元for文を使い3個の数字の順列6通りをすべて作り出す
プログラムを考えてください。
2番目x[1]のfor文から3番目進むには、
条件x[1]≠x[0]を満たしていることが条件となります。
これはif文で解決できます。
また、3番目x[2]に正しく数字が入ったときのみ
すなわち、x[2]≠x[0]かつx[2]≠x[1]に、
コンソールへ出力されます。
『かつ』は&&を使ってください。
具体的には、if(x[2]!=x[0] && x[2]!=x[1])です。
このコンソールへの出力は、関数g(int *x)に担わせ、
x[0]、x[1]、x[2]への入力は関数f(int *x)に担当させてください。
配列xはmainで宣言してください。
≠はC言語、C++では!=なのです。
今回は、かなり難問です。
30分ぐらい考えても分からないときは、
是非次話をご覧になってください。
尚、名称がないと説明しにくいですから、
3個の文字の順列を3次順列、
4個の文字の順列を4次順列、
・
・
などと名付けることにします。
第7講第10話へ 第2話へ
魔方陣 数独で学ぶ VBA 入門
数独のシンプルな解き方・簡単な解法の研究
VB講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)
初心者のための VC++による C言語 C++ 入門 基礎から応用まで第1部
eclipse java 入門
java 入門 サイト 基礎から応用まで
VC++ C言語 C++ 入門 初心者 基礎から応用まで
本サイトトップへ