8.奇数方陣(素数方陣を含む)および8・12・16方陣を作成するプログラム例
以下にプログラム例を示します。12方陣と16方陣についてはコンピュータ魔方陣を見つけるまでかなり時間がかかります。最新のペンティアムV500HZマシンを使っても、5分ぐらいかかるかもしれません。12または16方陣を計算させる際には、別の作業でもやっていてください。それ以外についてはあっという間に大量に作成してしまいます。
Turobo C++でテキストは作ってある。残念ながらTurobo C++のインデント(TAB)の部分は、インターネットエクスプローラーには反映されない。インデントがないとプログラムを理解するのは困難なので、ワープロを利用してスペースでインデントをとってある。しかし、不幸なことにワープロのスペースで作ったインデントは、C言語で読み込んでコンパイルする際に、エラーの原因になってしまう。C言語に読み込んだ際には、インデントは一度消して、コンパイルしていただきたい。また、インデントをTABで取り直しておくとプログラムを読む際に都合がいいと思う。
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#define MAX 100
#define MAH 50
void tanemoto(char g,char n);
void taneseisei(char s,char t,char n);
void gousei(char s,char t,char n);
unsigned int kai=0;
int *x;
unsigned int kn=0;
void main()
{
char n,m;
char i,j;
x=malloc(2*MAH*MAH);
clrscr();
printf("20以下の奇数または8,12,16のいずれかを入力してください。");
i=1;
while(i)
{
scanf("%d",&n);
if((n%2==1 || n==8 ||n==12 ||n==16)
&& n<20)
i=0;
else{
gotoxy(1,1);
clrscr();
printf("入力できるものは奇数か8,12,16のいずれかのみです。再入力してください。");
}
}
tanemoto(0,n);
gotoxy(5,23);
printf(" 何かキーを入力してください。");
getchar();
getchar();
}
void gousei(char s,char t,char n)
{
static int y[MAH][MAH];
register int i,j;
char k,l;
char *a,*b;
char ken=1,ken2=1,ii,ij,ik;
long int wa1,wa2;
for(i=0;i<n;i++){
for(j=0;j<n;j++){
y[i][j]=*(x+i*MAH+j)+n*(*(x+i*MAH+j+MAH*MAH)-1);
}
}
for(i=0;i<n;i++)
for(j=0;j<n;j++)
for(k=0;k<=i;k++)
for(l=0;l<n;l++){
if((k==i) &&
(l==j))break;
if(y[i][j]==y[k][l]){
ken=0;
goto end;
}
}
end:
if(ken==1)
for(i=0;i<n;i++){
wa1=0;
wa2=0;
for(j=0;j<n;j++){
wa1=wa1+y[i][j];
wa2=wa2+y[j][i];
}
if(wa1!=n*(n*n+1)/2 || wa2!=n*(n*n+1)/2){
ken=0;
}
/*
if(ken==1){
gotoxy((n+1)*4,i+3);
printf("%4d",wa1);
gotoxy(1+4*i,4+n);
printf("%4d",wa2);
}
*/
}
if(ken==1){
wa1=0;
wa2=0;
for(i=0;i<n;i++){
wa1=wa1+y[i][i];
wa2=wa2+y[i][n-i-1];
}
if(wa1!=n*(n*n+1)/2 || wa2!=n*(n*n+1)/2){
ken=0;
}
}
/*
if(ken==1){
gotoxy((n+1)*4,2);
printf("%4d",wa1);
gotoxy((n+1)*4,3+n);
printf("%4d",wa2);
}
*/
if(ken==1){
gotoxy(5,22);
printf("作成できた魔方陣の個数=%d",kai);
gotoxy(35,22);
printf("s=%2d",s);
gotoxy(45,22);
printf("t=%2d",t);
if(n<5)
kk=15;
else if(n<7)
kk=12;
else
kk=6;
if(n<7)
kk2=3;
else
kk2=2;
ii=kai%kk;
kai++;
for(i=0;i<n;i++)
for(j=0;j<n;j++){
ik=ii/kk2;
ij=ii%kk2;
gotoxy(3*j+1+(n+1)*ik*3,i+2+(n+1)*ij);
printf("%2d",y[i][j]);
}
}
}
void taneseisei(char s,char t,char n)
{
char j1,j2,i,j,m;
m=n/2;
if(n==9 || n==15)
for(i=0;i<n;i++)
for(j=0;j<n;j++)
*(x+i*MAH+n-j-1+MAH*MAH)=*(x+i*MAH+j);
for(i=1;i<n;i++)
for(j=0;j<n;j++){
j1=(j+s)%n;
j2=(j+t)%n;
*(x+i*MAH+j)=*(x+(i-1)*MAH+j1);
*(x+i*MAH+j+MAH*MAH)=*(x+(i-1)*MAH+j2+MAH*MAH);
/*
gotoxy(50+3*j,2+i);
printf("%3d",*(x+i*MAH+j));
gotoxy(50+3*j,3+i+n);
printf("%3d",*(x+i*MAH+j+MAH*MAH));
*/
}
}
void tanemoto(char g,char n)
{
char i,j,k,l,h=1;
k=1;
while(k<n+1){
h=1;
if(n==9 || n==15){
if(g==0 && k==1)
k=n/2+1;
if(g==0 && k>n/2+1)
break;
}
*(x+g)=k;
*(x+g+MAH*MAH)=k;
if(g<n/2){
gotoxy(50+3*g,23);
printf("%d",*(x+g));
}
for(i=0;i<g;i++){
if(*(x+i)==*(x+g)){
h=0;
break;
}
}
if(h==1){
if(g+1<n)
tanemoto(g+1,n);
else
for(i=1;i<n;i++){
for(j=1;j<n;j++){
if(i!=j){
taneseisei(i,j,n);
gousei(i,j,n);
}
}
}
}
k++;
}
}