|
|
|
@ -2,53 +2,28 @@
|
|
|
|
|
#include<stdlib.h>
|
|
|
|
|
#include<time.h>
|
|
|
|
|
#define range9(x) for(int x = 0; x < 9; x ++)
|
|
|
|
|
|
|
|
|
|
#define range81() for(int i = 0; i < 9; i ++) for(int j = 0; j < 9; j ++)
|
|
|
|
|
struct Sudoku{
|
|
|
|
|
int v[9][9];
|
|
|
|
|
int inc[9][9];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#define MAXSIZE 1000
|
|
|
|
|
#define DefautTop 100
|
|
|
|
|
struct Sudoku *M_PtrReg[MAXSIZE];
|
|
|
|
|
int PRtp = DefautTop, prtp = 0;
|
|
|
|
|
void ptrInit(){
|
|
|
|
|
for(int i = 0; i < PRtp; i ++)
|
|
|
|
|
M_PtrReg[i] = malloc(sizeof(struct Sudoku));
|
|
|
|
|
}
|
|
|
|
|
void ptrClear(){
|
|
|
|
|
for(int i = 0; i < PRtp; i ++)
|
|
|
|
|
free(M_PtrReg[i]);
|
|
|
|
|
}
|
|
|
|
|
struct Sudoku *ptrReg(){
|
|
|
|
|
return prtp < PRtp ? M_PtrReg[prtp++]: (M_PtrReg[prtp++] = malloc(sizeof(struct Sudoku)));
|
|
|
|
|
}
|
|
|
|
|
void ptrFree(){--prtp;}
|
|
|
|
|
struct Sudoku M_Sudoku[MAXSIZE];
|
|
|
|
|
int tp=0;
|
|
|
|
|
|
|
|
|
|
void sudokuClear(struct Sudoku *a){
|
|
|
|
|
range9(i)
|
|
|
|
|
range9(j)
|
|
|
|
|
a->v[i][j] = 0;
|
|
|
|
|
}
|
|
|
|
|
void sudokuCopy(struct Sudoku src, struct Sudoku *dst){
|
|
|
|
|
range9(i)
|
|
|
|
|
range9(j)
|
|
|
|
|
dst->v[i][j] = src.v[i][j];
|
|
|
|
|
}
|
|
|
|
|
void sudokufromArray(int src[9][9], struct Sudoku *dst){
|
|
|
|
|
range9(i)
|
|
|
|
|
range9(j)
|
|
|
|
|
dst->v[i][j] = src[i][j];
|
|
|
|
|
}
|
|
|
|
|
void sudokuClear(struct Sudoku *a){range81()a->inc[i][j] = 0;}
|
|
|
|
|
void sudokuCopy(struct Sudoku src, struct Sudoku *dst){range81()dst->inc[i][j] = src.inc[i][j];}
|
|
|
|
|
void sudokufromArray(int src[9][9], struct Sudoku *dst){range81()dst->inc[i][j] = src[i][j];}
|
|
|
|
|
void sudokuPrint(struct Sudoku a){
|
|
|
|
|
range9(i){
|
|
|
|
|
if(!(i % 3)) putchar('\n');
|
|
|
|
|
range9(j){
|
|
|
|
|
if(!(j % 3)) putchar(' ');
|
|
|
|
|
if(!a.v[i][j])
|
|
|
|
|
if(!a.inc[i][j])
|
|
|
|
|
putchar('.');
|
|
|
|
|
else
|
|
|
|
|
// putchar(a.v[i][j] + 48);
|
|
|
|
|
printf("%d", a.v[i][j]);
|
|
|
|
|
// putchar(a.inc[i][j] + 48);
|
|
|
|
|
printf("%d", a.inc[i][j]);
|
|
|
|
|
putchar(' ');
|
|
|
|
|
}
|
|
|
|
|
putchar('\n');
|
|
|
|
@ -57,23 +32,22 @@ void sudokuPrint(struct Sudoku a){
|
|
|
|
|
void initRandomSeed(){srand(time(NULL));}
|
|
|
|
|
struct Sudoku sudokuRandomGenerate(unsigned int fill){// %
|
|
|
|
|
fill %= 101;
|
|
|
|
|
struct Sudoku *res = ptrReg();
|
|
|
|
|
range9(i)
|
|
|
|
|
range9(j)
|
|
|
|
|
struct Sudoku *res = M_Sudoku + tp++;
|
|
|
|
|
range81()
|
|
|
|
|
if(rand()%100 <= fill)
|
|
|
|
|
res->v[i][j] = rand() % 9 + 1;
|
|
|
|
|
res->inc[i][j] = rand() % 9 + 1;
|
|
|
|
|
else
|
|
|
|
|
res->v[i][j] = 0;
|
|
|
|
|
res->inc[i][j] = 0;
|
|
|
|
|
return *res;
|
|
|
|
|
}
|
|
|
|
|
struct Sudoku tags;
|
|
|
|
|
int tag(struct Sudoku *a, int i, int j, int x, int y, struct Sudoku *tags){
|
|
|
|
|
if(i == x && j == y) return 0;
|
|
|
|
|
if(a->v[i][j] == a->v[x][y]){
|
|
|
|
|
printf("False:repetition found in (%d,%d) and (%d,%d) with the number {%d}\n", i+1, j+1, x+1, y+1, a->v[x][y]);
|
|
|
|
|
if(a->inc[i][j] && a->inc[i][j] == a->inc[x][y]){
|
|
|
|
|
printf("False:repetition found in (%d,%d) and (%d,%d) with the number {%d}\n", i+1, j+1, x+1, y+1, a->inc[x][y]);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
tags->v[x][y] |= (1 << a->v[i][j]);
|
|
|
|
|
tags->inc[x][y] |= (1 << a->inc[i][j]);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
int tagPoint(struct Sudoku *a, int i, int j, struct Sudoku *tags){
|
|
|
|
@ -83,12 +57,10 @@ int tagPoint(struct Sudoku *a, int i, int j, struct Sudoku *tags){
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
int tagsInit(struct Sudoku *a, struct Sudoku *tags){
|
|
|
|
|
range9(i)
|
|
|
|
|
range9(j)
|
|
|
|
|
tags->v[i][j] |= (1 << a->v[i][j]);
|
|
|
|
|
range9(i)
|
|
|
|
|
range9(j)
|
|
|
|
|
if(a->v[i][j] && tagPoint(a, i, j, tags))
|
|
|
|
|
range81()
|
|
|
|
|
tags->inc[i][j] |= (1 << a->inc[i][j]);
|
|
|
|
|
range81()
|
|
|
|
|
if(a->inc[i][j] && tagPoint(a, i, j, tags))
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
int sudokuJudge(struct Sudoku a){
|
|
|
|
@ -100,56 +72,53 @@ int sudokuJudge(struct Sudoku a){
|
|
|
|
|
}
|
|
|
|
|
void tagFindLeast(struct Sudoku *a, int *x, int *y, struct Sudoku *tags){
|
|
|
|
|
int minv = 10;
|
|
|
|
|
int mini=0, minj=0;
|
|
|
|
|
range9(i)
|
|
|
|
|
range9(j)
|
|
|
|
|
if(!a->v[i][j]){
|
|
|
|
|
*x = *y = 0;
|
|
|
|
|
range81()
|
|
|
|
|
if(!(a->inc[i][j])){
|
|
|
|
|
int cnt = 0;
|
|
|
|
|
range9(k)
|
|
|
|
|
cnt += (tags->v[i][j] >> k) & 1;
|
|
|
|
|
if(cnt < minv && cnt != 0){
|
|
|
|
|
minv = cnt;
|
|
|
|
|
mini = i;
|
|
|
|
|
minj = j;
|
|
|
|
|
}
|
|
|
|
|
cnt += !((tags->inc[i][j] >> (k+1)) & 1);
|
|
|
|
|
if(cnt < minv && cnt != 0)
|
|
|
|
|
minv = cnt,
|
|
|
|
|
*x = i,
|
|
|
|
|
*y = j;
|
|
|
|
|
}
|
|
|
|
|
*x = mini;
|
|
|
|
|
*y = minj;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
struct Sudoku *sudokuFill__(struct Sudoku *a, int unfillednum, struct Sudoku *tags){
|
|
|
|
|
struct Sudoku *pres, *t_tags;
|
|
|
|
|
if(!unfillednum){
|
|
|
|
|
pres = ptrReg();
|
|
|
|
|
pres = M_Sudoku + tp ++;
|
|
|
|
|
sudokuCopy(*a, pres);
|
|
|
|
|
sudokuPrint(*tags);
|
|
|
|
|
sudokuPrint(*a);
|
|
|
|
|
return pres;
|
|
|
|
|
}
|
|
|
|
|
int m=0, n=0;
|
|
|
|
|
tagFindLeast(a, &m, &n, tags);
|
|
|
|
|
printf("%d\n", unfillednum);
|
|
|
|
|
range9(i)
|
|
|
|
|
if(!((tags->v[m][n] >> i) & 1)){
|
|
|
|
|
a->v[m][n] = i;
|
|
|
|
|
t_tags = ptrReg();
|
|
|
|
|
if(!((tags->inc[m][n] >> (i+1)) & 1)){
|
|
|
|
|
t_tags = M_Sudoku + tp ++;
|
|
|
|
|
sudokuCopy(*tags, t_tags);
|
|
|
|
|
a->inc[m][n] = i+1;
|
|
|
|
|
tagPoint(a, m, n, t_tags);
|
|
|
|
|
// printf("step:%d:[%d %d]:%d\n", unfillednum, m+1, n+1, i+1);
|
|
|
|
|
// sudokuPrint(*a);
|
|
|
|
|
// getchar();
|
|
|
|
|
pres = sudokuFill__(a, unfillednum - 1, t_tags);
|
|
|
|
|
if(pres)
|
|
|
|
|
return pres;
|
|
|
|
|
a->v[m][n] = 0;
|
|
|
|
|
ptrFree();
|
|
|
|
|
a->inc[m][n] = 0;
|
|
|
|
|
tp --;
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
struct Sudoku *sudokuFill(struct Sudoku *a){
|
|
|
|
|
struct Sudoku tags;
|
|
|
|
|
struct Sudoku tags, res, *pres;
|
|
|
|
|
sudokuClear(&tags);
|
|
|
|
|
if(tagsInit(a, &tags)) return NULL;
|
|
|
|
|
int unfillednum = 0;
|
|
|
|
|
range9(i)
|
|
|
|
|
range9(j)
|
|
|
|
|
if(!a->v[i][j])
|
|
|
|
|
range81()
|
|
|
|
|
if(!a->inc[i][j])
|
|
|
|
|
unfillednum ++;
|
|
|
|
|
return sudokuFill__(a, unfillednum, &tags);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|