第17講 普遍版魔方陣自動生成プログラムの高速化 
第5話 仮屋崎座標作成プログラム解説その3
座標作成本体コード再掲
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;
    }
  }

}

解説

今話は Ⅱ 番号から座標への解説です。

   0
0 0 9 10 11 5
1 12 1 13 6 14
2 15 16 2 17 18
3 19 7 20 3 21
4 8 22 23 24 4

  for(i=0;i<n;i++){
    for(j=0;j<n;j++){
      x[b[i][j]]=j;
      y[b[i][j]]=i;
    }
  }
の動きを追っていきましょう。
i=0、j=0のとき
b[i][j]=b[0][0]=0
ですから、
x[b[i][j]]=x[0]=j=0
y[b[i][j]]=y[0]=i=0

i=0、j=1のとき
b[i][j]=b[0][1]=9
ですから、
x[b[i][j]]=x[9]=j=1
y[b[i][j]]=y[9]=i=0

i=0、j=2のとき
b[i][j]=b[0][2]=10
ですから、
x[b[i][j]]=x[10]=j=2
y[b[i][j]]=y[10]=i=0

   0
0 0 9 10 11 5
1 12 1 13 6 14
2 15 16 2 17 18
3 19 7 20 3 21
4 8 22 23 24 4

i=0、j=3のとき
b[i][j]=b[0][3]=11
ですから、
x[b[i][j]]=x[11]=j=3
y[b[i][j]]=y[11]=i=0

i=0、j=4のとき
b[i][j]=b[0][4]=5
ですから、
x[b[i][j]]=x[5]=j=4
y[b[i][j]]=y[5]=i=0

i=1、j=0のとき
b[i][j]=b[1][0]=12
ですから、
x[b[i][j]]=x[12]=j=0
y[b[i][j]]=y[12]=i=1

i=1、j=1のとき
b[i][j]=b[1][1]=1
ですから、
x[b[i][j]]=x[1]=j=1
y[b[i][j]]=y[1]=i=1

   0
0 0 9 10 11 5
1 12 1 13 6 14
2 15 16 2 17 18
3 19 7 20 3 21
4 8 22 23 24 4

i=1、j=2のとき
b[i][j]=b[1][2]=13
ですから、
x[b[i][j]]=x[13]=j=2
y[b[i][j]]=y[13]=i=1

i=1、j=3のとき
b[i][j]=b[1][3]=6
ですから、
x[b[i][j]]=x[6]=j=3
y[b[i][j]]=y[6]=i=1

i=1、j=4のとき
b[i][j]=b[1][4]=14
ですから、
x[b[i][j]]=x[14]=j=4
y[b[i][j]]=y[14]=i=1

    ・
    ・
    ・
省略した部分は是非ご自分でトレースしてください。
見事に座標が作られていることがお分かりになると思います。

解説は以上にします。次話では、このプログラムにランダムを組み込みます。
第5講 if文を理解しよう
 第3話 if文を使ったプログラミング
にランダムの使い方が説明してありますので、これを参考に組んでください。
ランダムを組み込むとはどういう意味かと申しますと、
すべてのセルにおいて1からはじめてn*nとfor文を組んでありますが、
1から始める必要はありません。
例えば、5次魔方陣を例にすれば
8,9,10,・・・,24,25,1,2,3,4,5,6,7
とfor文を動かしていってもよいのです。
この始まりをランダムにしたいということなのです。
そして、始まりをランダムにすると同時に、
増分も1である必要はありません。
n*nと公約数が1である数なら何でもよいのです。
5次魔方陣において増分を例えば11、始まりを14にすれば
14,25,11,22,8,19,5,16,2,13,24,10,21,7,18,4,15,1,12,23,9,20,6,17,3
となり、漏れなく重複なく1から25のすべての場合を動いているのがわかります。
これらの工夫を重ねると現在では最初の1つを見つけるのに数時間はかかってしまう6次魔方陣も作成できるようになります。
課題は、14,25,11,22,8,19,5,16,2,13,24,10,21,7,18,4,15,1,12,23,9,20,6,17,3という動きをいかに実現するかです。





第4話へ 第6話へ

戻る

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

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