第14講 ベクタを利用して6次魔方陣を作ろう!
第7話 第2のコードのミソ

void g(vector<vector<int>>::iterator m){
   int w;
   for(int i=0;i<3;i++){ //対角線交換
     for(int j=0;j<6;j++){
        if(i==j || 5-j==i){
          w=m[5-i][5-j];
          m[5-i][5-j]=m[i][j];
          m[i][j]=w;
        }
     }
   }
}
このコードを理解するには、
m[i][i]が右下がりの対角線を動き、
m[5-i][i]が右上がりの対角線を動く、
ことを把握しなければなりません。
m[i][i]は座標(i,i)に対応し
m[5-i][i]は座標(5-i,i)に対応しているからです。
座標(i,i)とき、

   0  1 2 3 4 5
 0 1 2 3  4 5 6
 1 7 8 9 10 11 12
 2 13 14 15 16 17 18
 3 19 20 21 22 23 24
 4 25 26 27 28 29 30
 5 31 32 33 34 35 36

左上から右下に動いていきます。

座標(5-i,i)とき、

   0  1 2 3 4 5
 0 1 2 3  4 5 6
 1 7 8 9 10 11 12
 2 13 14 15 16 17 18
 3 19 20 21 22 23 24
 4 25 26 27 28 29 30
 5 31 32 33 34 35 36

左下から右上に動いていきます。
尚、座標(i,5-i)の場合には
右上から左下へと逆の動きをします。
        if(i==j || 5-j==i)の
i==jの場合、
          w=m[5-i][5-j];
          m[5-i][5-j]=m[i][j];
          m[i][j]=w;

          w=m[5-i][5-i];
          m[5-i][5-i]=m[i][i];
          m[i][i]=w;
であり、

座標(5-i,i)バージョン

   0  1 2 3 4 5
 0 1 2 3  4 5 6
 1 7 8 9 10 11 12
 2 13 14 15 16 17 18
 3 19 20 21 22 23 24
 4 25 26 27 28 29 30
 5 31 32 33 34 35 36

に対応します。


        if(i==j || 5-j==i)の
5-j==iの場合、j==5-iであることに注意すれば
          w=m[5-i][5-j];
          m[5-i][5-j]=m[i][j];
          m[i][j]=w;

          w=m[5-i][i];
          m[5-i][i]=m[i][5-i];
          m[i][5-i]=w;
であり、

座標(5-i,i)バージョン

   0  1 2 3 4 5
 0 1 2 3  4 5 6
 1 7 8 9 10 11 12
 2 13 14 15 16 17 18
 3 19 20 21 22 23 24
 4 25 26 27 28 29 30
 5 31 32 33 34 35 36

に対応します。


void g(vector<vector<int>>::iterator m){
   int w;
   for(int i=0;i<3;i++){ //対角線交換
     for(int j=0;j<6;j++){
        if(i==j || 5-j==i){
          w=m[5-i][5-j];
          m[5-i][5-j]=m[i][j];
          m[i][j]=w;
        }
     }
   }
}
摩訶不思議に思えたこのコードも
i==jのときは、jをiに置き換えれば、
          w=m[5-i][5-i];
          m[5-i][5-i]=m[i][i];
          m[i][i]=w;
5-j==iときは、5-jをi、jを5-iと置き換えれば、
          w=m[5-i][i];
          m[5-i][i]=m[i][5-i];
          m[i][5-i]=w;
常識的な姿に姿態します。
結局、
void g(vector<vector<int>>::iterator m){
   int w;
   for(int i=0;i<3;i++){ //対角線交換
     for(int j=0;j<6;j++){
        if(i==j || 5-j==i){
          w=m[5-i][5-j];
          m[5-i][5-j]=m[i][j];
          m[i][j]=w;
        }
     }
   }
}

void g(vector<vector<int>>::iterator m){
   int w;
   for(int i=0;i<3;i++){ //対角線交換
     w=m[
5-i][5-i];
     m[5-i][5-i]=m[i][i];
     m[i][i]=w;
   }

   for(int i=0;i<3;i++){ //逆対角線交換
     w=m[5-i][i];
     m[5-i][i]=m[i][5-i];
     m[i][5-i]=w;
   }
}
と同じであることが明らかになったわけです。

第2のコードの謎が明らかになりました。

 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



では、左右の対称移動
すなわち、紺色のセルの交換をするにはどうしたらよいでしょうか。
ヒントを第8話で述べることにしましょう。

第6話へ 第8話へ



a

eclipse c++ 入門講義第1部へ

魔方陣 数独で学ぶ V
BA 入門
数独のシンプルな解き方・簡単な解法の研究
VB講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)
初心者のための VC++による C言語 C++ 入門 基礎から応用まで第1部
eclipse java 入門
java 入門 サイト 基礎から応用まで
VC++ C言語 C++ 入門 初心者 基礎から応用まで
本サイトトップへ