第9講 4次魔方陣と6次魔方陣の作成
第3話 for文による書き直し

前話解答例
v=a[0][0];
a[0][0]=a[3][3];
a[3][3]=v;
v=a[1][1];
a[1][1]=a[2][2];
a[2][2]=v;
v=a[0][3];
a[0][3]=a[3][0];
a[3][0]=v;
v=a[1][2];
a[1][2]=a[2][1];
a[2][1]=v;
の部分を次のように変更する。
v=a[0][1];
a[0][1]=a[3][2];
a[3][2]=v;
v=a[0][2];
a[0][2]=a[3][1];
a[3][1]=v;
v=a[1][0];
a[1][0]=a[2][3];
a[2][3]=v;
v=a[2][0];
a[2][0]=a[1][3];
a[1][3]=v;


ところで

 1  2  3  4
 5  6  7  8
 9 10 11 12
13 14 15 16

      

16  2  3 13
 5 11 10  8
 9  7  6 12
 4 14 15  1


v=a[0][0];
a[0][0]=a[3][3];
a[3][3]=v;
v=a[1][1];
a[1][1]=a[2][2];
a[2][2]=v;
v=a[0][3];
a[0][3]=a[3][0];
a[3][0]=v;
v=a[1][2];
a[1][2]=a[2][1];
a[2][1]=v;

にしても

 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

v=a[0][1];
a[0][1]=a[3][2];
a[3][2]=v;
v=a[0][2];
a[0][2]=a[3][1];
a[3][1]=v;
v=a[1][0];
a[1][0]=a[2][3];
a[2][3]=v;
v=a[2][0];
a[2][0]=a[1][3];
a[1][3]=v;
にしても少し芸がありません。
同じようなことを人間が繰り返しているからです。
繰り返しは、やはりコンピュータにやらせるべきです。
そこで、この二つを2次元のfor文を使って書き直してみましょう。
つまり、2つのプログラムを
for(i=0;i<?;i++){
  for(j=0;j<?;j++){
        
        ・
        ・

  }
}
のように書き直して頂きたいと思います。
皆さんには?
        
        ・
        ・

の部分を考えて頂きたいと思います。
ただし、
        ・
        ・
        ・
        
の部分は、必ずしも3行とは限りません。

まず前半

 1  2  3  4
 5  6  7  8
 9 10 11 12
13 14 15 16

      

16  2  3 13
 5 11 10  8
 9  7  6 12
 4 14 15  1

から考えていきましょう。
解答例は、例によって20行下に書きましょう。




















解答例
for(i=0;i<2;i++){
  for(j=0;j<2;j++){
    if(i==0){
      v=a[j][j];
      a[j][j]=a[3-j][3-j];
      a[3-j][3-j]=v;
    }
    if(i==1){
      v=a[j][3-j];
      a[j][3-j]=a[3-j][j];
      a[3-j][j]=v;
    }
  }
}

(コピーペースト用
for(i=0;i<2;i++){
for(j=0;j<2;j++){
if(i==0){
v=a[j][j];
a[j][j]=a[3-j][3-j];
a[3-j][3-j]=v;
}
if(i==1){
v=a[j][3-j];
a[j][3-j]=a[3-j][j];
a[3-j][j]=v;
}
}
}

もともと12行だったものが14行に増えて、御利益がないと思うかもしれませが、
より複雑なプログラムを組むときの参考として、
このようなやり方も是非覚えていだきたいと思います。
それに、よりスマートに
for(i=0;i<2;i++){
  for(j=0;j<2;j++){
    if(i==0){
      v=a[j][j];
      a[j][j]=a[3-j][3-j];
      a[3-j][3-j]=v;
    }
    if(i==1){
      v=a[j][3-j];
      a[j][3-j]=a[3-j][j];
      a[3-j][j]=v;
    }
  }
}

for(i=0;i<2;i++){
  for(j=0;j<4;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<2;i++){
for(j=0;j<4;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;
}
}
}

とすることもできます。これなら9行です。
|はorを意味します。
条件(i==j) || (i==3-j))


対角線を意味しています。i==jが赤を、i==3-jが水色に対応してます。

さて、2次元ループと指定がありましたので、for文の2次元にしましたが、
1次元でもできます。
皆さん、考えてみましょう。解答例は、20行下に示します。






















解答例
for(i=0;i<2;i++){
  v=a[i][i];
  a[i][i]=a[3-i][3-i];
  a[3-i][3-i]=v;
}
for(i=0;i<2;i++){
  v=a[i][3-i];
  a[i][3-i]=a[3-i][i];
  a[3-i][i]=v;
}

(コピーペースト用
for(i=0;i<2;i++){
v=a[i][i];
a[i][i]=a[3-i][3-i];
a[3-i][3-i]=v;
}
for(i=0;i<2;i++){
v=a[i][3-i];
a[i][3-i]=a[3-i][i];
a[3-i][i]=v;
}

2次元の解答例にしても、
1次元の解答例にしても皆さんの頭の中には?マークが浮かんでいるのではないでしょうか。
初心者の方には、確かに非常に難しいプログラムですので、
次話で、トレースしながら詳しく解説していきたいと思います。




第2話へ 第4話へ



初心者のためのjava 入門 基礎から応用まで
初心者のための VC++による C言語 入門 C++ 入門 基礎から応用まで第1部
初心者のための VC++による C言語 入門 C++ 入門 基礎から応用まで第2部
初心者のための VC++による C言語 入門 C++ 入門 基礎から応用まで第3部
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすい vb 入門 vba 入門 基礎から応用まで 第1部
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座へ