第9講 4次魔方陣と6次魔方陣の作成
第6話 andとorの否定
解答例
for(i=0;i<3;i++){
for(j=0;j<3;j++){
if((i!=j) && (i!=3-j) ){
v=a[i][j];
a[i][j]=a[3-i][3-j];
a[3-i][3-j]=v;
}
}
}
(コピーペースト用
for(i=0;i<3;i++){
for(j=0;j<3;j++){
if((i!=j) && (i!=3-j) ){
v=a[i][j];
a[i][j]=a[3-i][3-j];
a[3-i][3-j]=v;
}
}
}
)
解説
一般に、条件
pまたはq
の否定は、
(pでない)かつ(qでない)
になります。
また、pかつqの否定は
(pでない)または(qでない)
となります。
「かつ」という言葉に聞き慣れていない人もいると思いますが、
pかつq
は条件pも条件qも同時に満たすことを表します。
それに対して、
pまたはq
は条件pを満たすか、条件qを満たしていればよいのです。
どちらか一方の条件を満たしていればよいのですから、
両方の条件を満たすpかつqの状態でもいいのです。
集合の図を書いてみましょう。
条件pを満たす集合をP、
条件qを満たす集合をQ、
pかつqを満たす集合をP∩Q、
pまたはqを満たす集合をP∪Qと表すことにしますと、
下図のようになります。
したがって、条件pまたはqの否定を表す集合は、
となり、条件pまたはqの否定は(pでない)かつ(qでない)となります。
また、条件pかつqの否定を表す集合は、
となり、条件pかつqの否定は(pでない)または(qでない)になります。
以上の解説から
(i==j) || (i==3-j)の否定は、
(i!=j) && (i!=3-j) であることがご理解頂けるかと思います。
for(i=0;i<3;i++){
for(j=0;j<3;j++){
if((i!=j) && (i!=3-j) ){
v=a[i][j];
[i][j]=a[3-i][3-j];
a[3-i][3-j]=v;
}
}
}
をトレースしてみましょう。
for(i=0;i<3;i++){
for(j=0;j<3;j++)
から、i、jの動いていく範囲は
です。さらに、if((i!=j) && (i!=3-j) )
によって、対角線と逆対角線が除外されますので、動く範囲はさらにに限定され、
となります。
それらのセルが
と交換されます。
なお、
for(i=0;i<4;i++){
for(j=0;j<4;j++){
if((i!=j) && (i!=3-j) ){
v=a[i][j];
[i][j]=a[3-i][3-j];
a[3-i][3-j]=v;
}
}
}
としてしまうと、交換対象セルが
となってしまい、2度交換され元に戻っていまいますので、注意しましょう。
例えば、i=0、j=1のとき
が交換され、
となりますが、
i=3、j=2のとき
が再び交換され、
と元に戻ってしまうのです。
だから、
for(i=0;i<3;i++){
for(j=0;j<3;j++){
if((i!=j) && (i!=3-j) ){
v=a[i][j];
a[i][j]=a[3-i][3-j];
a[3-i][3-j]=v;
}
}
}
でなければならないのです。
具体的にトレースしてみましょう。
T i=0 の場合
@ j=0のとき、
i=0、j=0よりi=jなので、条件(i!=j) && (i!=3-j)に抵触し、if文は実行されません。
A j=1のとき
i=0、j=1で条件(i!=j) && (i!=3-j)がクリアされ、if文が実行されます。
v=a[0][1];
a[0」[1]=a[3][2];
a[3][2]=v; により
が交換される。
B j=2のとき、
i=0、j=2なので条件(i!=j) && (i!=3-j)がクリアされ、if文は実行されて、
v=a[0][2];
a[0」[2]=a[3][1];
a[3][1]=v; により
が交換される。
U i=1 の場合
@ j=0のとき、
i=1、j=0なので条件(i!=j) && (i!=3-j)をクリアして、if文が実行され、
v=a[1][0];
a[1」[0]=a[2][3];
a[2][3]=v; により
の交換が実行される。
A j=1のとき
i=j=1となり、条件(i!=j) && (i!=3-j)がクリアされず、if文は実行されません。
B j=2のとき、
i=1、j=2なのでi=3-jとなり、
条件(i!=j) && (i!=3-j)がクリアされず、if文は実行されません。
V i=2 の場合
@ j=0のとき、
i=2、j=0なので条件(i!=j) && (i!=3-j)をクリアして、if文が実行され、
v=a[2][0];
a[2」[0]=a[1][3];
a[1][3]=v; により
の交換が実行される。
A j=1のとき
i=2、j=1なのでi=3-jとなり、条件(i!=j) && (i!=3-j)がクリアされず、if文は実行されません。
B j=2のとき、
i=2、j=2なのでi=jとなり、
条件(i!=j) && (i!=3-j)がクリアされず、if文は実行されません。
以上より
1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 |
↓
1 | 15 | 14 | 4 |
12 | 6 | 7 | 9 |
8 | 10 | 11 | 5 |
13 | 3 | 2 | 16 |
が成功していることがわかります。
以上で4次魔方陣は終わりにして、次に6次魔方陣に挑戦しましょう。
作り方を復習しておくと、
最初に自然配列を作ります。
1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 |
31 | 32 | 33 | 34 | 35 | 36 |
そして、
1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 |
31 | 32 | 33 | 34 | 35 | 36 |
ピンクは中心に対して点対称移動、
薄緑は中央の直線に対して上下に線対称移動、
紺色は中央の直線に対して左右に線対称移動
を行います。すると、
36 | 32 | 4 | 3 | 5 | 31 |
12 | 29 | 27 | 10 | 26 | 7 |
19 | 17 | 22 | 21 | 14 | 18 |
13 | 20 | 16 | 15 | 23 | 24 |
25 | 11 | 9 | 28 | 8 | 30 |
6 | 2 | 33 | 34 | 35 | 1 |
36 | 32 | 4 | 3 | 5 | 31 |
12 | 29 | 27 | 10 | 26 | 7 |
19 | 17 | 22 | 21 | 14 | 18 |
13 | 20 | 16 | 15 | 23 | 24 |
25 | 11 | 9 | 28 | 8 | 30 |
6 | 2 | 33 | 34 | 35 | 1 |
では皆さん、4次魔方陣の作り方を参考にして6次魔方陣の作成に挑戦しましょう。
交換は、a[0][0]=a[5][5]のような手動ではなく、
for文で自動で行ってください。
繰り返しは、人間の行うものではありませんよ。
なかなか簡単にはいきませんが、粘り強く試行錯誤を繰り返しましょう。
完成したら、第7話をクリックしましょう。
繰り返しますが、あくまで解答例であって第7話と同じである必要はありませんよ。
for文を使っていて(今回は条件が指定されているからです)6次魔方陣ができていればどんなプログラミングでも正解です。
ただ、異なるプログラミングをした場合でも第7、8話は参考になるはずですから必ず熟読してください。
初心者のためのjava 入門 基礎から応用まで
初心者のための VC++による C言語 入門 C++ 入門 基礎から応用まで第1部
初心者のための VC++による C言語 入門 C++ 入門 基礎から応用まで第2部
初心者のための VC++による C言語 入門 C++ 入門 基礎から応用まで第3部
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすい vb 入門 vba 入門 基礎から応用まで 第1部
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座へ