第17講 普遍版魔方陣自動生成プログラムの高速化 
第3話 仮屋崎座標作成プログラム解説その1
座標作成本体コード再掲
void f0(){
  int i,j,c;
  int b[10][10];
  for(i=0;i<n;i++){
    for(j=0;j<n;j++){
      b[i][j]=-1;
    }
  }
  for(i=0;i<n;i++){
    b[i][i]=i;
  }
  c=n-1;
  for(i=0;i<n;i++){
    if(b[i][n-1-i]==-1){
      c++;
      b[i][n-1-i]=c;
    }
  }
  for(i=0;i<n;i++){
    for(j=0;j<n;j++){
      if(b[i][j]==-1){
        c++;
        b[i][j]=c;
      }
    }
  }
  for(i=0;i<n;i++){
    for(j=0;j<n;j++){
      x[b[i][j]]=j;
      y[b[i][j]]=i;
    }
  }
}

解説
このプログラムは、
Ⅰ 番号付け
Ⅱ 番号から座標へ
という流れで組むまれいます。
そして、Ⅰの番号付けは
ⅰ すべてのセルに-1を割り振る
ⅱ -1の付いたセルに順に0から番号を割り振る
の2段の手順を踏んでいて、
さらにⅱの番号割り振りは、
① 対角線
② 逆対角線
③ 残りのセル
という順番で行われています。

Ⅰ 番号付けから詳しく解説していきます。
まず、何故ⅰ すべてのセルに-1を割り振っているのでしょうか。
これは重複を防ぐためです。
番号は0から始まりますので、
0より小さい整数であれば何でもいいのです。
すべてに-2を割り振ってもよいし、ランダムに負の整数を割り振ってもよいのです。
重複を防ぐためとはどういうことでしょうか。
① 対角線
に関しては重複の可能性はありません。
しかし、② 逆対角線の番号割り振りに関しては

0 5
1 6
2
3
4

奇数次の場合真ん中で必ず重複してしまいます。
-1が割り振ってあるセルだけ数字を置き換えるというルールを作っておかないと、
上の例では2が7に置き換わってしまいます。
ですが、本来は

0 5
1 6
2
7 3
8 4

2はそのままで1つ飛んで7、8と割り振らなければなりませんね。
1つ飛ぶために
  for(i=0;i<n;i++){
    if(b[i][n-1-i]==-1){
      c++;
      b[i][n-1-i]=c;
    }
  }
if文が設けられているわけです。

また、③ 残りのセルの割り振りは
  for(i=0;i<n;i++){
    for(j=0;j<n;j++){
      if(b[i][j]==-1){
        c++;
        b[i][j]=c;
      }
    }
  }
行列を順に埋めていきますから、
if文がなければ上の表の番号をすべて書き換えてしまうことになります。





第2話へ 第4話へ

戻る

C言語 C++講義第1部へ
VB講義へ
VB講義基礎へ

vc++講義へ第1部へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)