第28講 細胞構成法による魔方陣の作成△
第9話 素数次魔方陣解答例解説
コード例
・
・
・
#pragma
endregion
private: System::Void button1_Click(System::Object^ sender,
System::EventArgs^ e) {
・
・
・
if(n!=3 )f0(0); //5次7次の場合を新設
・
・
・
void f0(int g){
if(s==200)return;
int i,j,k,l,h;
for(i=0;i<n;i++){
a1[0][g]=i;
h=1;
if(g>0){
for(j=0;j<g;j++){
if(a1[0][g]==a1[0][j]){
h=0;
break;
}
}
}
if(h==1){
if(g+1<n){
f0(g+1);
}
else{
for(j=1;j<n;j++){
for(k=0;k<n;k++){
l=(2*j+k)%n;
a1[j][l]=a1[0][k];
}
}
f00(0);
}
}
}
}
void f00(int g){
if(s==200)return;
int i,j,k,l,h;
for(i=0;i<n;i++){
a2[0][g]=i;
h=1;
if(g>0){
for(j=0;j<g;j++){
if(a2[0][g]==a2[0][j]){
h=0;
break;
}
}
}
if(h==1){
if(g+1<n){
f00(g+1);
}
else{
for(j=1;j<n;j++){
for(k=0;k<n;k++){
l=(3*j+k)%n;
a2[j][l]=a2[0][k];
}
}
array<String^>^ w=gcnew array<String^>(15);
for(j=0;j<n;j++){
for(k=0;k<n;k++){
w[k]=(n*a1[j][k]+a2[j][k]+1).ToString();
}
dataGridView1->Rows->Add(w);
}
for(j=0;j<14;j++)w[j]=L"";
dataGridView1->Rows->Add(w);
s++;
if(s==200)return;
}
}
}
}
・
・
・
解説
f0もf00も順列を作成する再帰的関数です。
ですから、本質的には細胞作成関数と同じです。
f0が1個目の種の作成を担当し、f00が2個目の種の作成を担当しています。
f0のおいて順列の完成すると、
for(j=1;j<n;j++){
for(k=0;k<n;k++){
l=(2*j+k)%n;
a1[j][l]=a1[0][k];
}
}
において、ずらし法による種の作成が行われます。
ミソは、l=(2*j+k)%n; にあります。
jは行を担当し、kは列を担当することに注意しながら、
シミュレーションをしてみましょう。
Ⅰ j=1の場合
ⅰ k=0のとき
l=(2*j+k)%n=(2*1+0)%5=2%5=2
から、a1[j][l]=a1[0][k];はa1[1][2]=a1[0][0];
0 | 1 | 2 | 3 | 4 | |
0 | 1 | 2 | 3 | 4 | 5 |
1 | 1 |
ⅱ k=1のとき
l=(2*j+k)%n=(2*1+1)%5=3%5=3
から、a1[j][l]=a1[0][k];はa1[1][3]=a1[0][1];
0 | 1 | 2 | 3 | 4 | |
0 | 1 | 2 | 3 | 4 | 5 |
1 | 1 | 2 |
ⅲ k=2のとき
l=(2*j+k)%n=(2*1+2)%5=4%5=4
から、a1[j][l]=a1[0][k];はa1[1][4]=a1[0][2];
0 | 1 | 2 | 3 | 4 | |
0 | 1 | 2 | 3 | 4 | 5 |
1 | 1 | 2 | 3 |
ⅳ k=3のとき
l=(2*j+k)%n=(2*1+3)%5=5%5=0
から、a1[j][l]=a1[0][k];はa1[1][0]=a1[0][3];
0 | 1 | 2 | 3 | 4 | |
0 | 1 | 2 | 3 | 4 | 5 |
1 | 4 | 1 | 2 | 3 |
ⅴ k=4のとき
l=(2*j+k)%n=(2*1+4)%5=6%5=1
から、a1[j][l]=a1[0][k];はa1[1][1]=a1[0][4];
0 | 1 | 2 | 3 | 4 | |
0 | 1 | 2 | 3 | 4 | 5 |
1 | 4 | 5 | 1 | 2 | 3 |
Ⅱ j=2の場合
ⅰ k=0のとき
l=(2*j+k)%n=(2*2+0)%5=4%5=4
から、a1[j][l]=a1[0][k];はa1[2][4]=a1[0][0];
0 | 1 | 2 | 3 | 4 | |
0 | 1 | 2 | 3 | 4 | 5 |
1 | 4 | 5 | 1 | 2 | 3 |
2 | 1 |
ⅱ k=1のとき
l=(2*j+k)%n=(2*2+1)%5=5%5=5
から、a1[j][l]=a1[0][k];はa1[2][0]=a1[0][1];
0 | 1 | 2 | 3 | 4 | |
0 | 1 | 2 | 3 | 4 | 5 |
1 | 4 | 5 | 1 | 2 | 3 |
2 | 2 | 1 |
ⅲ k=2のとき
l=(2*j+k)%n=(2*2+2)%5=6%5=1
から、a1[j][l]=a1[0][k];はa1[2][1]=a1[0][2];
0 | 1 | 2 | 3 | 4 | |
0 | 1 | 2 | 3 | 4 | 5 |
1 | 4 | 5 | 1 | 2 | 3 |
2 | 2 | 3 | 1 |
ⅳ k=3のとき
l=(2*j+k)%n=(2*2+3)%5=7%5=2
から、a1[j][l]=a1[0][k];はa1[2][2]=a1[0][3];
0 | 1 | 2 | 3 | 4 | |
0 | 1 | 2 | 3 | 4 | 5 |
1 | 4 | 5 | 1 | 2 | 3 |
2 | 2 | 3 | 4 | 1 |
ⅴ k=4のとき
l=(2*j+k)%n=(2*2+4)%5=8%5=3
から、a1[j][l]=a1[0][k];はa1[2][3]=a1[0][4];
0 | 1 | 2 | 3 | 4 | |
0 | 1 | 2 | 3 | 4 | 5 |
1 | 4 | 5 | 1 | 2 | 3 |
2 | 2 | 3 | 4 | 3 | 1 |
Ⅲ j=3の場合
ⅰ k=0のとき
l=(2*j+k)%n=(2*3+0)%5=6%5=1
から、a1[j][l]=a1[0][k];はa1[3][1]=a1[0][0];
0 | 1 | 2 | 3 | 4 | |
0 | 1 | 2 | 3 | 4 | 5 |
1 | 4 | 5 | 1 | 2 | 3 |
2 | 2 | 3 | 4 | 3 | 1 |
3 | 1 |
ⅱ k=1のとき
l=(2*j+k)%n=(2*3+1)%5=7%5=2
から、a1[j][l]=a1[0][k];はa1[3][2]=a1[0][1];
0 | 1 | 2 | 3 | 4 | |
0 | 1 | 2 | 3 | 4 | 5 |
1 | 4 | 5 | 1 | 2 | 3 |
2 | 2 | 3 | 4 | 3 | 1 |
3 | 1 | 2 |
ⅲ k=2のとき
l=(2*j+k)%n=(2*3+2)%5=8%5=3
から、a1[j][l]=a1[0][k];はa1[3][3]=a1[0][2];
0 | 1 | 2 | 3 | 4 | |
0 | 1 | 2 | 3 | 4 | 5 |
1 | 4 | 5 | 1 | 2 | 3 |
2 | 2 | 3 | 4 | 3 | 1 |
3 | 1 | 2 | 3 |
ⅳ k=3のとき
l=(2*j+k)%n=(2*3+3)%5=9%5=4
から、a1[j][l]=a1[0][k];はa1[3][4]=a1[0][3];
0 | 1 | 2 | 3 | 4 | |
0 | 1 | 2 | 3 | 4 | 5 |
1 | 4 | 5 | 1 | 2 | 3 |
2 | 2 | 3 | 4 | 3 | 1 |
3 | 1 | 2 | 3 | 4 |
ⅴ k=4のとき
l=(2*j+k)%n=(2*3+4)%5=10%5=0
から、a1[j][l]=a1[0][k];はa1[3][0]=a1[0][4];
0 | 1 | 2 | 3 | 4 | |
0 | 1 | 2 | 3 | 4 | 5 |
1 | 4 | 5 | 1 | 2 | 3 |
2 | 2 | 3 | 4 | 3 | 1 |
3 | 5 | 1 | 2 | 3 | 4 |
Ⅳ j=4の場合
ⅰ k=0のとき
l=(2*j+k)%n=(2*4+0)%5=8%5=3
から、a1[j][l]=a1[0][k];はa1[4][3]=a1[0][0];
0 | 1 | 2 | 3 | 4 | |
0 | 1 | 2 | 3 | 4 | 5 |
1 | 4 | 5 | 1 | 2 | 3 |
2 | 2 | 3 | 4 | 3 | 1 |
3 | 5 | 1 | 2 | 3 | 4 |
4 | 1 |
ⅱ k=1のとき
l=(2*j+k)%n=(2*4+1)%5=9%5=4
から、a1[j][l]=a1[0][k];はa1[4][4]=a1[0][1];
0 | 1 | 2 | 3 | 4 | |
0 | 1 | 2 | 3 | 4 | 5 |
1 | 4 | 5 | 1 | 2 | 3 |
2 | 2 | 3 | 4 | 3 | 1 |
3 | 5 | 1 | 2 | 3 | 4 |
4 | 1 | 2 |
ⅲ k=2のとき
l=(2*j+k)%n=(2*4+2)%5=10%5=5
から、a1[j][l]=a1[0][k];はa1[4][0]=a1[0][2];
0 | 1 | 2 | 3 | 4 | |
0 | 1 | 2 | 3 | 4 | 5 |
1 | 4 | 5 | 1 | 2 | 3 |
2 | 2 | 3 | 4 | 3 | 1 |
3 | 5 | 1 | 2 | 3 | 4 |
4 | 3 | 1 | 2 |
ⅳ k=3のとき
l=(2*j+k)%n=(2*4+3)%5=11%5=1
から、a1[j][l]=a1[0][k];はa1[4][1]=a1[0][3];
0 | 1 | 2 | 3 | 4 | |
0 | 1 | 2 | 3 | 4 | 5 |
1 | 4 | 5 | 1 | 2 | 3 |
2 | 2 | 3 | 4 | 3 | 1 |
3 | 5 | 1 | 2 | 3 | 4 |
4 | 3 | 4 | 1 | 2 |
ⅴ k=4のとき
l=(2*j+k)%n=(2*4+4)%5=12%5=2
から、a1[j][l]=a1[0][k];はa1[4][2]=a1[0][4];
0 | 1 | 2 | 3 | 4 | |
0 | 1 | 2 | 3 | 4 | 5 |
1 | 4 | 5 | 1 | 2 | 3 |
2 | 2 | 3 | 4 | 3 | 1 |
3 | 5 | 1 | 2 | 3 | 4 |
4 | 3 | 4 | 5 | 1 | 2 |
見事に1個目の種が完成しています。
f00については皆さんご自分でトレースしてみましょう。
さて、f00の
for(j=0;j<n;j++){
for(k=0;k<n;k++){
w[k]=(n*a1[j][k]+a2[j][k]+1).ToString();
}
dataGridView1->Rows->Add(w);
}
においては、2つの種の合成が行われています。
では、次の課題を提示してこの話を終了しましょう。
次なる課題は、細胞を合成して、
3 | 4 | 3 | 1 | 3 | 1 |
1 | 2 | 4 | 2 | 4 | 2 |
3 | 2 | 3 | 4 | 1 | 2 |
1 | 4 | 1 | 2 | 4 | 3 |
3 | 1 | 3 | 4 | 1 | 3 |
4 | 2 | 1 | 2 | 2 | 4 |
縦・横・対角線の合成が一致するようにしてください。
この講での一番の難所です。
がんばりましょう。
尚、色対応を見ればお分かりのように、細胞は同じ細胞がいくつか使われていても何も問題がありません。
つまり、すべてが異なる細胞である必要はありません。
これが出来れば魔方陣超高速作成まで後一歩です。
第8話へ 第10話へ
VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual
Basic入門基礎講座