第19講 座標の工夫による魔方陣自動生成ソフトの高速化

第3話 仮屋崎方式

10 11
12 13
14 15


4
10 11
12 13 14
15 16 17 18
19 20 21
4 22 23 24

赤の番号はx、濃紺の番号はy、ピンクの番号はgに対応)
番号付けとそれに対応するy座標とx座標はいかにしたら実現できるでしょうか。
これについて、最初私は偶数の場合と奇数の場合に分けて、
次のように複雑なプログラムを組みました。
             ・
             ・
             ・
           if(n%2==1)g1(n);
           if(n%2==0)g2(n);

           f(0);
             ・
             ・
             ・
        }
        void g1(char n){
          char i,j,m;
          m=n/2;
          for(i=0;i<n*n;i++){
            if(i<n){
              x[i]=i;
              y[i]=i;
            }
            else if(i<2*n-1){
              x[i]=2*n-i-1;
              y[i]=i-n;
              if(x[i]<=y[i]){
                x[i]--;
                y[i]++;
              }
            }
            else if(i<2*n+(n*n-3*n)/2){
              x[i]=(i-2*n+1)%(n-2);
              y[i]=(i-2*n+1)/(n-2);
              if(x[i]>=y[i])x[i]++;
              if(x[i]>=n-y[i]-1)x[i]++;
            }
            else if(i<3*n-1+(n*n-3*n)/2){
              x[i]=i-2*n-(n*n-3*n)/2;
              y[i]=m;
              if(x[i]>=y[i])x[i]++;
            }
            else{
              x[i]=(i-2*n)%(n-2);
              y[i]=(i-2*n)/(n-2);
              if(x[i]>=n-y[i]-1)x[i]++;
              if(x[i]>=y[i])x[i]++;
            }
          }
        }
        void g2(char n){
          char i,m;
          m=n/2;
          for(i=0;i<n*n;i++){
            if(i<n){
              x[i]=i;
              y[i]=i;
            }
            else if(i<2*n){
              x[i]=2*n-i-1;
              y[i]=i-n;
            }
            else if(i<(m+1)*n){
              x[i]=(i-2*n)%(n-2);
              y[i]=(i-2*n)/(n-2);
              if(x[i]>=y[i])x[i]++;
              if(x[i]>=n-y[i]-1)x[i]++;
            }
            else{
              x[i]=(i-2*n)%(n-2);
              y[i]=(i-2*n)/(n-2);
              if(x[i]>=n-y[i]-1)x[i]++;
              if(x[i]>=y[i])x[i]++;
            }
          }
        }

初心者のための VC++ 入門 (C++ 入門) 講義 基礎から応用まで(第2部)
第2話 番号付けの改良より引用)
g1が偶数番であり、g2が奇数番です。
興味がおありの方は、VC++講義の第2話 番号付け
をお読み頂ければと思いますが、
本サイトの読者の仮屋崎さんから、
天才的なアイデアが寄せられましたので、
その骨格部分をVC++講義より、
引用します。
        void g(char n){
           char i,j;
           char b[10][10];
           int cn=n;
           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;
           }
           for(i=0;i<n;i++){
             if(b[i][n-1-i]==-1){
               b[i][n-1-i]=cn;
               cn++;
             }
           }
           for(i=0;i<n;i++){
             for(j=0;j<n;j++){
               if(b[i][j]==-1){
                 b[i][j]=cn;
                 cn++;
               }
             }
           }
           for(i=0;i<n;i++){
             for(j=0;j<n;j++){
               x[b[i][j]]=j;
               y[b[i][j]]=i;
             }
          }
       }
これを参考にして、番号付けとそれに対応する座標を作成する関数を作り、
その番号を

10 11
12 13
14 15


4
10 11
12 13 14
15 16 17 18
19 20 21
4 22 23 24


q
v
表示させましょう。


第2話へ 第4話へ

a

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

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