第17講 関数の再帰的呼び出しによる3次・4次魔方陣ソフトの改良
第7話 奇数版枠番号付けの解説その2
else if(i<2*n+(n*n-3*n)/2){
x[i]=(i-2*n+1)%(n-2);
y[i]=(i-2*n+1)/(n-2);
if(x[i]>=y[i])x[i]++;
if(x[i]>=n-y[i]-1)x[i]++;
}
else if(i<3*n-1+(n*n-3*n)/2){
x[i]=i-2*n-(n*n-3*n)/2;
y[i]=m;
if(x[i]>=y[i])x[i]++;
}
else{
x[i]=(i-2*n)%(n-2);
y[i]=(i-2*n)/(n-2);
if(x[i]>=n-y[i]-1)x[i]++;
if(x[i]>=y[i])x[i]++;
}
まず、i<2*n+(n*n-3*n)/2から解説しましょう。
0 | 1 | 2 | 3 | 4 | |
0 | 0 | 9 | 10 | 11 | 5 |
1 | 12 | 1 | 13 | 6 | 14 |
2 | 15 | 16 | 2 | 17 | 18 |
3 | 19 | 7 | 20 | 3 | 21 |
4 | 8 | 22 | 23 | 24 | 4 |
nに5を代入すると、2×5+(5×5−3×5)÷2=15
15 |
になることが分かります。
ですから、iの対象範囲は9から14までとなります。
なぜうまく15となるのでしょうか。
実は次の計算をしています。
2×n−1+{n×n−(2×n−1)−(n−1)}÷2
=2×n−1+(n×n−3×n+2)÷2
=2×n−1+(n×n−3×n)÷2+1
=2×n+(n×n−3×n)÷2
対角線と逆対角線でセル数が2×n−1個ですから、
□9□ |
は2×n−1番目です。
番号は0から始まるからです。
では、{n×n−(2×n−1)−(n−1)}÷2においては何を計算しているのでしょうか。
対角線と逆対角線のセルと
中央行の中央のセル以外のセルを除いたセルすなわち
2 | 15 | 16 | □2□ | 17 | 18 |
の
□2□ |
を除いたセルとの
の合計数を全セル数から引いています。
−(2×n−1)で対角線と逆対角線の合計セル数を引いて、
−(n−1)で
2 | 15 | 16 | □2□ | 17 | 18 |
中央行の中央のセルを除いた
セル数分を引いています。
0 | □9□ | 10 | 11 | 5 |
12 | 1 | 13 | 6 | 14 |
そして、それを2で割れば左表の水色以外のセル(9,10,11,13,13,14)数
になるのはお分かりでしょうか。
では、
else if(i<3*n-1+(n*n-3*n)/2){
x[i]=i-2*n-(n*n-3*n)/2;
y[i]=m;
if(x[i]>=y[i])x[i]++;
}
のi<3*n-1+(n*n-3*n)/2は何でしょうか。
実はこれは
2×n−1+{n×n−(2×n−1)−(n−1)}÷2+(n−1)
=2×n−1+(n×n−3×n+2)÷2+n−1
=2×n−1+(n×n−3×n)÷2+1+n−1
=3×n−1+(n×n−3×n)÷2
=3*n−1+(n*n−3*n)/2
つまり前回の2*n+(n*n-3*n)/2に(n-1)を加えているのです。
(n-1)は
15 | 16 | □2□ | 17 | 18 |
の
□2□ |
を除いたセル数です。
ですから3*n-1+(n*n-3*n)/2は
19 |
を指すことになりましてi<3*n-1+(n*n-3*n)/2の指し示す範囲は、
15,16,17,18とうまくいきます。
x[i]=i-2*n-(n*n-3*n)/2;
y[i]=m;
if(x[i]>=y[i])x[i]++;
については、y[i]=m;のmはn/2でしたからm=2でうまくいっています。
はi-2*n-(n*n-3*n)/2はiから2*n+(n*n-3*n)/2を引いていますので、
0,1,2,3と動いていき、if(x[i]>=y[i])x[i]++;によって、
0,1,3,4となります。
最後の
else{
x[i]=(i-2*n)%(n-2);
y[i]=(i-2*n)/(n-2);
if(x[i]>=n-y[i]-1)x[i]++;
if(x[i]>=y[i])x[i]++;
}
の対象は残りの
19 | 7 | 20 | 3 | 21 |
8 | 22 | 23 | 24 | 4 |
19,20,21,22,23,24
であることはお分かりでしょう。
尚、n=5の場合で説明しましたが、奇数ならいくつでも成り立つ普遍的(汎用性の広い)プログラムです。
是非、皆さんn=7やn=9などでトレースして普遍性(一般性)を確認されて下さい。
第17講第6話 第17講第8話へ
VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual
Basic入門基礎講座