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++;
  }
}
 


 

戻る
 


 
                             
                     
                    


 

進む
 


 
                             
                     
                    


 

目次へ
 


 

魔方陣新HPへ
魔方陣トップへ数学研究室へ

パワーポイント講義へ

小中学生のための魔方陣授業


上にメニューが示されてない場合は、下のロゴ右脳数学(直観数学)またはURLをクッリク!


http://www5b.biglobe.ne.jp/~suugaku/