//--------------------------------------------------------------------------- // 箱詰めパズル ヘキソミノ 11×19 基本解のみ 010131 鈴木 昇 //--------------------------------------------------------------------------- #include #include #include #include #include #include #pragma hdrstop void go4(int) ;void color();void color2();void table4();void delay() ;void check(); void alter(int);void print();void print1();void print2();void print3();void print4(); int ks[35]={19, 4,34,10,23,3,12,7,13,28,2,33,5,8,6,32,29,27, 24,16,17,30,15,0,11,31,21,25,26,18,9,14,20,1,22}; unsigned int num,numc,l,an; int M,N,M0,N0,M1,N1,N2,N3,N4,N5,N9,MN,MN1,MN2,MNC,NG,komasuu; int d,p,pt,cw,cl,l1,r,ck,kk,kr; int koma[35],same[35],name[35],h[35][8][5],ban[280],band[280],banc[280]; FILE *fp;clock_t t0,t1;float t;char cc,co[10],cs[20],bc[50][50]; //--------------------------------------------------------------------------- USERES("Pack_Hex.res"); //--------------------------------------------------------------------------- int main() { int i; textmode(84);komasuu=35;strcpy(cs,"ヘキソミノ"); st1:printf ("\n ヘキソミノを求めます。(11×19)\n"); printf ("\n 1 経過表示 2 解表示 3 テキスト出力 4 HTML出力(容量大) 5 解数のみ 6 終了"); printf ("\n\n 出力モードを選択して下さい? ");_setcursortype(_NORMALCURSOR); do {gotoxy(32,wherey());printf(" \b");cscanf("%c",&cc);}while (cc<'0'|| cc>'6'); p=cc-'0';printf("\n");if (p==6) return 0;if (p==0) { check(); goto st1;} pt=0; if (p==3) pt=1;else if (p==4) {p=3;pt=2;} else if (p==5) p=4; if (pt==1) {strcpy(co,"wri");fp=fopen("pack.wri","w");} if (pt==2) {strcpy(co,"htm");fp=fopen("pack.htm","w");print3();} M0=19;N0=12;MN=M0*N0;N=N0;M=M0;N9=N0-1; N1=N+1;M1=M+1;MN1=N1*M-1+N1;MN2=N1*M1+N1; N2=N1+N1;N3=N2+N1;N4=N3+N1;N5=N4+N1;MNC=MN1-N2; table4();t=1.24;ck=num=0;d=l1=1;l=1000; // an=4294967295 まで printf ("\n 解をいくつ求めますか? ");printf(" \b");cscanf("%d",&an);randomize(); t0=t1=clock();_setcursortype(_NOCURSOR);if (an<=0) {printf("\n");goto st1;} if (p>2) printf ("\n\n %s %2d × %2d \n\n !!!計算中!!!\r",cs,N9,M0); if (p<3) {clrscr();printf(" %s %2d × %d ",cs,N9,M0); printf ("( + 速く - 遅く 0 最速 r 停止 s 一時停止 e 中止 )\n\n !!計算中!!");} if (p<2) {gotoxy(2,5) ;printf("┌");gotoxy(4+2*M0,5) ;printf("┐"); gotoxy(2,6+N0);printf("└");gotoxy(4+2*M0,6+N0);printf("┘");} if (p==3) {if (pt==1) fprintf (fp,"\n %s %2d × %d \n\n\n",cs,N9,M0);} st3:kk=cl=r=0;num=numc=0; for (i=0;iMN1-N) band[i]=3;} band[N1+1]=2;band[N1+N-1]=2;band[MN1-N+1]=2;band[MN1-1]=2;band[131]=4; for (i=0;i0;i--) {int j=random(i+1);int k=ks[i];ks[i]=ks[j];ks[j]=k;} go4(N1+1); if (r==2) goto st3; gotoxy(1,wherey()+1);if (d==5) goto st1; if (p>2 || r==0){printf ("\n %s %2d × %2d ",cs,N9,M0); if (an==num) printf (" 解 %4u 個 計算しました。 \n\n",num); else if (num>0) printf (" 解は全部で %4u 個 でした。\n\n",num); else printf (" 解はありませんでした。\n\n");} if (p==3 && num>0) printf (" 結果は \"pack.%3s\" に出力しました。",co); if (p>2) printf (" (Total Time %.3fsec)\n\a",(clock()-t0)/CLK_TCK); if (p==3) fclose(fp);if (p<3) printf("\n"); goto st1; } //--------------------------------------------------------------------------- void go4(int s) // 再帰的用法 ヘキソミノ { int i,j,k,s0,s1,s2,s3,s4,w; if (r) return;if (s>MNC) { if (same[ 3]>0||same[ 4]>0||same[ 5]>0||same[ 6]>0||same[11]>0||same[12]>0) return; if (same[13]>0||same[14]>0||same[15]>0||same[19]>0||same[20]>0||same[23]>0) return; if (same[24]>0||same[25]>0||same[26]>0||same[27]>0||same[28]>0) return; if (same[29]>0||same[30]>0||same[32]>0||same[33]>0||same[34]>0) return;} for (k=0;k2) {if (num%l1==0) {printf(" 解 %4u 発見\n",num); if (num==l) {l*=10;l1*=10;}}} if (num>=an) {r=1;return;} } if (r) return; back: band[s+1 ]++;band[s0+1 ]++;band[s1+1 ]++;band[s2+1 ]++;band[s3+1 ]++;band[s4+1 ]++; band[s+N1]++;band[s0+N1]++;band[s1+N1]++;band[s2+N1]++;band[s3+N1]++;band[s4+N1]++; band[s0-1]++;band[s1-1 ]++;band[s2-1 ]++;band[s3-1 ]++;band[s4-1 ]++; band[s1-N1]++;band[s2-N1]++;band[s3-N1]++;band[s4-N1]++; ban[s]=ban[s0]=ban[s1]=0;ban[s2]=ban[s3]=ban[s4]=0; } same[i]++; } //if (num==0) if (++kk>kr) {r=2;return;} } //--------------------------------------------------------------------------- void print(void) // 解の出力 { if (p<3) print1(); else if (pt==1) print2(); else print4(); } //--------------------------------------------------------------------------- void print1(void) // 解の表示 { int i,j; gotoxy(2,3);color(); if (p==2) {printf("解 %5u \n\n",num);ck=0;} if (p==1) if (ck) printf("解 %5u 発見      \n\n",num); else printf("解 %5u 経過 %5u \n\n",num,++numc); for (i=N1;i \n"); fprintf(fp," \n"); fprintf(fp,"%s \n",cs); fprintf(fp,"

%s

\n",cs); } //--------------------------------------------------------------------------- void print4(void) // 解のファイル出力 HTML形式 { int i,j,k; color(); fprintf(fp,"

解 %2u

\n",num); fprintf(fp,"
\n"); //fprintf(fp,"
\n"); // HP用 fprintf(fp," \n"); fprintf(fp," \n \n"); for (j=N1;j   \n",bc[k]); } fprintf(fp," \n"); for (i=1+N1;i \n"); for (j=i;j  \n",bc[k]); } fprintf(fp," \n"); } fprintf(fp,"
\n"); //fprintf(fp,"
\n"); // HP用 fprintf(fp,"
\n"); fprintf(fp,"

       

\n"); fprintf(fp," \n"); fprintf(fp," \n"); fclose(fp);fp=fopen("pack.htm","a"); } //--------------------------------------------------------------------------- void color() // 色を付ける { int i,j; NG=1; for (i=N1;i0 && ban[j]!=ban[j+ 1] && banc[j]==banc[j+ 1]) {alter(j);continue;} if (ban[j+N1]>0 && ban[j]!=ban[j+N1] && banc[j]==banc[j+N1]) {alter(j);continue;} if (ban[j- 1]>0 && ban[j]!=ban[j- 1] && banc[j]==banc[j- 1]) {alter(j);continue;} if (ban[j-N1]>0 && ban[j]!=ban[j-N1] && banc[j]==banc[j-N1]) alter(j); } } } //--------------------------------------------------------------------------- void alter(int b) // 色の変更 { int i,j,color,color2,a,kc[7]={9,10,11,12,13,14,15}; for (i=N1;i0 && ban[j]!=ban[j+ 1]) kc[banc[j+ 1]-9]=0; if (ban[j+N1]>0 && ban[j]!=ban[j+N1]) kc[banc[j+N1]-9]=0; if (j>=1) {if (ban[j- 1]>0 && ban[j]!=ban[j- 1]) kc[banc[j- 1]-9]=0;} if (j>=N1) {if (ban[j-N1]>0 && ban[j]!=ban[j-N1]) kc[banc[j-N1]-9]=0;} } } } if (kc[1]>0) {color=kc[1];goto en;} if (kc[0]>0) {color=kc[0];goto en;} // 色を決める if (kc[6]>0) {color=kc[6];goto en;} if (kc[2]>0) {color=kc[2];goto en;} if (kc[4]>0) {color=kc[4];goto en;} if (kc[3]>0) {color=kc[3];goto en;} if (kc[5]>0) {color=kc[5];goto en;} NG=1; color2=banc[b]; if (b>=N2 && banc[b-N1]>0 && ban[b]!=ban[b-N1]) {color=banc[b-N1];a=-N1;goto e1;} if (b>N1 && banc[b- 1]>0 && ban[b]!=ban[b- 1]) {color=banc[b- 1];a=-1 ;goto e1;} if ( banc[b+ 1]>0 && ban[b]!=ban[b+ 1]) {color=banc[b+ 1];a= 1 ;goto e1;} color=banc[b+N1];a= N1; e1: for (i=N1;i=koma[i2]) break; } if (j2=koma[i2]) break; }} gotoxy(45,2);printf("( Enter 次へ 0 戻る e 中止 ) ");nn+=koma[i2];gotoxy(2,2); cprintf("%s %2d 種目 %2d 通り  計 %2d 通り\n\n\r",cs,i2+1,koma[i2],nn); for (i=0;i0) {textbackground(10);cprintf(" ");} else {textbackground( 0);cprintf(" ");} } } textbackground(0);for (i=0;i