第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*
)%n=(2*)%5=2%5=
     から、a1[j][l]=a1[0][k];はa1[
1][2]=a1[0][0]; 

 
       

  ⅱ k=1のとき 
     l=(2*
)%n=(2*)%5=3%5=
     から、a1[j][l]=a1[0][k];はa1[
1][3]=a1[0][1]; 

 
     

  ⅲ k=2のとき 
     l=(2*
)%n=(2*)%5=4%5=
     から、a1[j][l]=a1[0][k];はa1[
1][4]=a1[0][2]; 

 
   

  ⅳ k=3のとき 
     l=(2*
)%n=(2*)%5=5%5=
     から、a1[j][l]=a1[0][k];はa1[
1][0]=a1[0][3]; 

 
 

  ⅴ k=4のとき 
     l=(2*
)%n=(2*)%5=6%5=
     から、a1[j][l]=a1[0][k];はa1[
1][1]=a1[0][4]; 

 

Ⅱ j=2の場合
  ⅰ 
k=0のとき 
     l=(2*
)%n=(2*)%5=4%5=
     から、a1[j][l]=a1[0][k];はa1[
2][4]=a1[0][0]; 

 
         

  ⅱ k=1のとき 
     l=(2*
)%n=(2*)%5=5%5=
     から、a1[j][l]=a1[0][k];はa1[
2][0]=a1[0][1]; 

 
       

  ⅲ k=2のとき 
     l=(2*
)%n=(2*)%5=6%5=
     から、a1[j][l]=a1[0][k];はa1[
2][1]=a1[0][2]; 

 
     

  ⅳ k=3のとき 
     l=(2*
)%n=(2*)%5=7%5=
     から、a1[j][l]=a1[0][k];はa1[
2][2]=a1[0][3]; 

 
   

  ⅴ k=4のとき 
     l=(2*
)%n=(2*)%5=8%5=
     から、a1[j][l]=a1[0][k];はa1[
2][3]=a1[0][4]; 

 
 

Ⅲ j=3の場合
  ⅰ 
k=0のとき 
     l=(2*
)%n=(2*)%5=6%5=
     から、a1[j][l]=a1[0][k];はa1[
3][1]=a1[0][0]; 

 
 
       

  ⅱ k=1のとき 
     l=(2*
)%n=(2*)%5=7%5=
     から、a1[j][l]=a1[0][k];はa1[
3][2]=a1[0][1]; 

 
 
     

  ⅲ k=2のとき 
     l=(2*
)%n=(2*)%5=8%5=
     から、a1[j][l]=a1[0][k];はa1[
3][3]=a1[0][2]; 

 
 
   

  ⅳ k=3のとき 
     l=(2*
)%n=(2*)%5=9%5=
     から、a1[j][l]=a1[0][k];はa1[
3][4]=a1[0][3]; 

 
 
 

  ⅴ k=4のとき 
     l=(2*
)%n=(2*)%5=10%5=
     から、a1[j][l]=a1[0][k];はa1[
3][0]=a1[0][4]; 

 
 

Ⅳ j=4の場合
  ⅰ 
k=0のとき 
     l=(2*
)%n=(2*)%5=8%5=3
     から、a1[j][l]=a1[0][k];はa1[
4][3]=a1[0][0]; 

 
 
       

  ⅱ k=1のとき 
     l=(2*
)%n=(2*)%5=9%5=
     から、a1[j][l]=a1[0][k];はa1[
4][4]=a1[0][1]; 

 
 
     

  ⅲ k=2のとき 
     l=(2*
)%n=(2*)%5=10%5=
     から、a1[j][l]=a1[0][k];はa1[
4][0]=a1[0][2]; 

 
 
   

  ⅳ k=3のとき 
     l=(2*
)%n=(2*)%5=11%5=
     から、a1[j][l]=a1[0][k];はa1[
4][1]=a1[0][3]; 

 
 
 

  ⅴ k=4のとき 
     l=(2*
)%n=(2*)%5=12%5=
     から、a1[j][l]=a1[0][k];はa1[
4][2]=a1[0][4]; 

 
 

見事に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入門基礎講座

l>