#include #include #include #define range9(x) for(int x = 0; x < 9; x ++) struct Sudoku{ int inc[9][9]; }; #define MAXSIZE 1000 struct Sudoku *M_PtrReg[MAXSIZE]; int PRtp = 0; void ptrInit(){ for(int i = 0; i < MAXSIZE; i ++) M_PtrReg[i] = (struct Sudoku *)malloc(sizeof(struct Sudoku)); } void ptrClear(){ for(int i = 0; i < MAXSIZE; i ++) free(M_PtrReg[i]); } struct Sudoku *ptrReg(){return M_PtrReg[PRtp++];} void ptrFree(){--PRtp;} void sudokuClear(struct Sudoku *a){ range9(i) range9(j) a->inc[i][j] = 0; } void sudokuCopy(struct Sudoku src, struct Sudoku *dst){ range9(i) range9(j) dst->inc[i][j] = src.inc[i][j]; } void sudokufromArray(int src[9][9], struct Sudoku *dst){ range9(i) range9(j) 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.inc[i][j]) putchar('.'); else // putchar(a.inc[i][j] + 48); printf("%d", a.inc[i][j]); putchar(' '); } putchar('\n'); } } void initRandomSeed(){srand(time(NULL));} struct Sudoku sudokuRandomGenerate(unsigned int fill){// % fill %= 101; struct Sudoku *res = ptrReg(); range9(i) range9(j) if(rand()%100 <= fill) res->inc[i][j] = rand() % 9 + 1; else 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->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->inc[x][y] |= (1 << a->inc[i][j]); return 0; } int tagPoint(struct Sudoku *a, int i, int j, struct Sudoku *tags){ range9(k) if(tag(a, i, j, i, k, tags)||tag(a, i, j, k, j, tags)||tag(a, i, j, i/3*3+k/3, j/3*3+k%3, tags)) return 1; return 0; } int tagsInit(struct Sudoku *a, struct Sudoku *tags){ range9(i) range9(j) tags->inc[i][j] |= (1 << a->inc[i][j]); range9(i) range9(j) if(a->inc[i][j] && tagPoint(a, i, j, tags)) return 1; } int sudokuJudge(struct Sudoku a){ struct Sudoku tags; sudokuClear(&tags); if(tagsInit(&a, &tags)) return 1; printf("True:Valid initial Sudoku matrix!\n"); return 0; } 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->inc[i][j]){ int cnt = 0; range9(k) cnt += (tags->inc[i][j] >> k) & 1; if(cnt < minv && cnt != 0){ minv = cnt; mini = i; minj = 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(); sudokuCopy(*a, pres); sudokuPrint(*tags); return pres; } int m=0, n=0; tagFindLeast(a, &m, &n, tags); range9(i) if(!((tags->inc[m][n] >> i) & 1)){ a->inc[m][n] = i; t_tags = ptrReg(); sudokuCopy(*tags, t_tags); tagPoint(a, m, n, t_tags); // sudokuPrint(*a); // getchar(); pres = sudokuFill__(a, unfillednum - 1, t_tags); if(pres) return pres; a->inc[m][n] = 0; ptrFree(); } return NULL; } struct Sudoku *sudokuFill(struct Sudoku *a){ struct Sudoku tags, res, *pres; sudokuClear(&tags); if(tagsInit(a, &tags)) return NULL; int unfillednum = 0; range9(i) range9(j) if(!a->inc[i][j]) unfillednum ++; printf("%d", unfillednum); return sudokuFill__(a, unfillednum, &tags); } int main(){ ptrInit(); initRandomSeed(); struct Sudoku a; sudokuCopy(sudokuRandomGenerate(10), &a); printf("The original Sudoku matrix: \n"); sudokuPrint(a); if(sudokuJudge(a)){ printf("No solution!\n"); ptrClear(); return 0; } struct Sudoku *pres = sudokuFill(&a); if(!pres){ printf("No solution!\n"); ptrClear(); return 0; } printf("The solution of Sudoku matrix:\n"); sudokuPrint(*pres); printf("%d", PRtp); ptrClear(); }