//================================================== // ナンバープレイス問題作成プログラム // // // Windowsの場合はコマンドプロンプトで Make_Number_Place.exe として実行 // 結果は // 問題_(日時).txtで保存される // // コンパイル方法(gccの場合) // // gcc Make_Number_Place.c -o Make_Number_Place.exe // // (c)2022 Yasuo Ikushima //================================================== #include#include #include #include #include #define MAXLIST 81 #define DEFLEN 128 int NumberPlace[MAXLIST]; int NumberPlace_ans[MAXLIST]; int NumberPlace_tmp[MAXLIST]; int NumberPlace_min[MAXLIST]; char randum_list[DEFLEN]; char matrix99[MAXLIST][DEFLEN]; // = [] int blunk_no; FILE *fout; unsigned int rseed; void make_matrix2(); int dup_check(int i,int j,int k,int l); int random_choice(); void randum_list_remove(int rn); void print_matrix(int *out_table); void fprint_matrix(int *out_table); void masu_blank(); int kai_check(); void in_matrix99(int n,int rn); void sub_rand() { int i; for(i = 0; i < 10 ; i ++) fprintf(stderr,"%d\n",(rand() % 9) + 1); return; } //================================================== // メインルーチン //================================================== int main(int argc,char *argv[]) { int lopx; int lopx2; int max_blunk_no; int min_blunk_no; int i,j; int kai_chk_count; int min_z_no,z_no; unsigned int ui,uj,uk; char outFileName[DEFLEN]; max_blunk_no = 64; //57 min_blunk_no = 52; //52 blunk_no = max_blunk_no; min_z_no = 100; srand((unsigned int)time(NULL)); // 現在時刻の情報で初期化 lopx = 1; while(lopx == 1) { fprintf(stderr,"Start\n"); // 乱数でマトリックスを作成 make_matrix2(); print_matrix(NumberPlace); // 穴を開けるまえのテーブルのコピーを作成 for(i = 0; i < MAXLIST ; i++) { NumberPlace_ans[i] = NumberPlace[i]; } // 解の重複チェック kai_chk_count = 0; min_z_no = 100; fprintf(stderr,"%d\n",blunk_no); lopx2 = 1; while(lopx2 == 1) { // ランダムマトリックスに空欄を作る masu_blank(); z_no = kai_check(); if (z_no < min_z_no) { min_z_no = z_no; fprintf(stderr,"blunk_no=%d,kai_chk_count=%d,min_z_no=%d\n",blunk_no,kai_chk_count,min_z_no); for(i = 0; i < MAXLIST ; i++) { NumberPlace_min[i] = NumberPlace[i]; } } kai_chk_count = kai_chk_count + 1; if (z_no < 1) { lopx = 0; lopx2 = 0; } if (kai_chk_count >= 1000000) { kai_chk_count = 0; blunk_no = blunk_no - 1; fprintf(stderr,"%d\n",blunk_no); if (blunk_no == min_blunk_no) { blunk_no = max_blunk_no; lopx2 = 0; } } } } time_t t = time(NULL); struct tm *local = localtime(&t); localtime(&t); sprintf(outFileName,"問題_%04d%02d%02d_%02d%02d.txt", (local->tm_year + 1900), (local->tm_mon + 1), (local->tm_mday),(local->tm_hour),(local->tm_min)); fout = fopen( outFileName, "w" ); fprintf(stderr,"Ans Matrix\n"); fprintf(fout,"Ans Matrix\n"); print_matrix(NumberPlace_ans); fprint_matrix(NumberPlace_ans); fprintf(stderr,"Blank Matrix %d\n",blunk_no); fprintf(fout,"Blank Matrix %d\n",blunk_no); print_matrix(NumberPlace_min); fprint_matrix(NumberPlace_min); fprintf(stderr,"End of Program\n"); fprintf(fout,"End of Program\n"); return(0); } //================================================== // 乱数でマトリックスを作成 //================================================== void make_matrix2() { int i,j; int n,n_total,n1,l; int n0,k,retv,i0; int n_max; for(i = 0; i < MAXLIST ; i ++) NumberPlace[i] = 0; n = 0; n_max = 0; n_total = 0; while(n < MAXLIST) { if (n > n_max) { n_max = n; } //m = i * (9 * 3) + j * 9 + k * 3 + l i = (int)(n / (9 * 3)); n0 = n - (i * (9 * 3)); j = (int)(n0 / 9); n1 = n0 - (j * 9); k = (int)(n1 / 3); l = n1 - (k * 3); sprintf(randum_list,"123456789"); retv = 1; while (retv == 1) { retv = dup_check(i,j,k,l); // retv 0: len(randum_list) == 0 // retv 1: 0 < len(randum_list) // retv -1: n = n + 1 } if (retv == 0) { n = 0; for(i0 = 0; i0 < MAXLIST ; i0 ++) NumberPlace[i0] = 0; } if (retv == -1) { n = n + 1; n_total = n_total + 1; } } return; } //================================================== // 重複が無いかチェック //================================================== int dup_check(int i,int j,int k,int l) { int rn,icount,k0,l0,m0,m,i0,j0; if (strlen(randum_list) == 0) return(0); rn = random_choice(); m = i * (9 * 3) + j * 9 + k * 3 + l; // 横チェック icount = 0; while(icount == 0) { for (k0 = 0; k0 < 3 ; k0 ++) { for (l0 = 0 ; l0 < 3 ; l0 ++) { m0 = i * (9 * 3) + j * 9 + k0 * 3 + l0; if (NumberPlace[m0] == rn) { randum_list_remove(rn); icount = icount + 1; return(icount); } } } if (icount == 0) icount = -1; } if (icount > 0) return(icount); // 縦チェック icount = 0; while(icount == 0) { for (i0 = 0; i0 < 3 ; i0 ++) { for (j0 = 0; j0 < 3 ; j0 ++) { m0 = i0 * (9 * 3) + j0 * 9 + k * 3 + l; if (NumberPlace[m0] == rn) { randum_list_remove(rn); icount = icount + 1; return(icount); } } } if (icount == 0) icount = -1; } if (icount > 0) return(icount); // 3x3ブロックチェック icount = 0; while(icount == 0) { for (j0 = 0 ; j0 < 3 ; j0 ++) { for (l0 = 0; l0 < 3 ; l0 ++) { m0 = i * (9 * 3) + j0 * 9 + k * 3 + l0; if (NumberPlace[m0] == rn) { randum_list_remove(rn); icount = icount + 1; return(icount); } } } if (icount == 0) icount = -1; } if (icount > 0) return(icount); NumberPlace[m] = rn; return(icount); } //================================================== // マトリックス表示 //================================================== void print_matrix(int *out_table) { int i,j,k,ilen; char s[DEFLEN]; for (i = 0 ; i < 9 ; i ++) { sprintf(s,"[%d] ",(i + 1)); for (j = 0; j < 9 ; j ++) { k = i * 9 + j; ilen = strlen(s); if (out_table[k] == 0) { sprintf(&s[ilen]," "); } else { sprintf(&s[ilen]," %d",out_table[k]); } } fprintf(stderr,"%s\n",s); } } //================================================== // マトリックスファイル出力 //================================================== void fprint_matrix(int *out_table) { int i,j,k,ilen; char s[DEFLEN]; for (i = 0 ; i < 9 ; i ++) { sprintf(s,"[%d] ",(i + 1)); for (j = 0; j < 9 ; j ++) { k = i * 9 + j; ilen = strlen(s); if (out_table[k] == 0) { sprintf(&s[ilen]," "); } else { sprintf(&s[ilen]," %d",out_table[k]); } } fprintf(fout,"%s\n",s); } } //================================================== // ランダムマトリックスに空欄を作る //================================================== void masu_blank() { int i,n,org_val,rn; // 穴を開けるまえのテーブルから復元 for (i = 0; i < MAXLIST ; i++) NumberPlace[i] = NumberPlace_ans[i]; n = blunk_no; //55 while(n > 0) { rn = rand() % MAXLIST; if (NumberPlace[rn] > 0) { org_val = NumberPlace[rn]; NumberPlace[rn] = 0; n = n - 1; } } return; } //================================================== // 解の重複チェック //================================================== int kai_check() { int n,nval; int z0; int i,n0,j,n1,k,l,k0,l0,m0; int rn; int count_1,i0,z_no,j0; for (n = 0; n < MAXLIST ; n ++) { NumberPlace_tmp[n] = NumberPlace[n]; } while(1) { z_no = 0; for (n = 0; n < MAXLIST ; n ++) { nval = NumberPlace_tmp[n]; if (nval == 0) z_no = z_no + 1; sprintf(matrix99[n],"%d123456789",nval); } for (n = 0; n < MAXLIST ; n ++) { i = (int)(n / (9 * 3)); n0 = n - (i * (9 * 3)); j = (int)(n0 / 9); n1 = n0 - (j * 9); k = (int)(n1 / 3); l = n1 - (k * 3); if (NumberPlace_tmp[n] == 0) { // 横チェック for (k0 = 0; k0 < 3 ; k0 ++) { for (l0 = 0 ; l0 < 3 ; l0 ++) { m0 = i * (9 * 3) + j * 9 + k0 * 3 + l0; rn = NumberPlace_tmp[m0]; in_matrix99(n,rn); } } // 縦チェック for (i0 = 0 ; i0 < 3 ; i0 ++) { for (j0 = 0 ; j0 < 3 ; j0 ++) { m0 = i0 * (9 * 3) + j0 * 9 + k * 3 + l; rn = NumberPlace_tmp[m0]; in_matrix99(n,rn); } } // 3x3ブロックチェック for (j0 = 0 ; j0 < 3 ; j0 ++) { for (l0 = 0 ; l0 < 3 ; l0 ++) { m0 = i * (9 * 3) + j0 * 9 + k * 3 + l0; rn = NumberPlace_tmp[m0]; in_matrix99(n,rn); } } } } count_1 = 0; for (n = 0 ; n < MAXLIST ; n ++) { if (strlen(matrix99[n]) == 2) { count_1 = count_1 + 1; NumberPlace_tmp[n] = NumberPlace_ans[n]; z_no = z_no - 1; } } if (count_1 == 0) break; } return(z_no); } //================================================== // random.choice(randum_list) //================================================== int random_choice() { int ilen,iret,num,i,j; char tmp[10]; ilen = strlen(randum_list); if (ilen > 0) { num = (rand() % ilen); iret = randum_list[num] - 0x30; } else { iret = 0; } return(iret); } //================================================== // randum_list.remove(rn) //================================================== void randum_list_remove(int rn) { int i,j; char tmp[10]; int ilen,num,iret; ilen = strlen(randum_list); j = 0; if (ilen > 0) { for (i = 0 ; i < (ilen + 1) ; i ++) { iret = randum_list[i] - '0'; if (iret != rn) { tmp[j] = randum_list[i]; j ++; } } tmp[j] = 0; sprintf(randum_list,"%s",tmp); } return; } //================================================== // if rn in matrix99[n][1] // matrix99[n][1].remove(rn) //================================================== void in_matrix99(int n,int rn) { int i,ilen,j,k; char tmp[DEFLEN]; ilen = strlen(matrix99[n]); tmp[0] = matrix99[n][0]; k = 1; if (ilen > 1) { for (i = 1; i < ilen ; i ++) { j = matrix99[n][i] - '0'; if (j != rn) { tmp[k] = matrix99[n][i]; k ++; } } tmp[k] = 0; sprintf(matrix99[n],"%s",tmp); } return; }