第19講 座標の工夫による魔方陣自動生成ソフトの高速化
第3話 仮屋崎方式
0 | 1 | 2 | 3 | |
0 | 0 | 8 | 9 | 4 |
1 | 10 | 1 | 5 | 11 |
2 | 12 | 6 | 2 | 13 |
3 | 7 | 14 | 15 | 3 |
0 | 1 | 2 | 3 | 4 | |
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 |
(赤の番号は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;
}
}
}
これを参考にして、番号付けとそれに対応する座標を作成する関数を作り、
その番号を
0 | 1 | 2 | 3 | |
0 | 0 | 8 | 9 | 4 |
1 | 10 | 1 | 5 | 11 |
2 | 12 | 6 | 2 | 13 |
3 | 7 | 14 | 15 | 3 |
0 | 1 | 2 | 3 | 4 | |
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 |
表示させましょう。