ナンバープレイスC言語ソースコード
//==================================================
// ナンバープレイス問題作成プログラム
// 
// 
// 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;
}


戻る