You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
3.6 KiB

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define range9(x) for(int x = 0; x < 9; x ++)
1 year ago
#define range81() for(int i = 0; i < 9; i ++) for(int j = 0; j < 9; j ++)
struct Sudoku{
1 year ago
int inc[9][9];
};
#define MAXSIZE 1000
1 year ago
struct Sudoku M_Sudoku[MAXSIZE];
int tp=0;
1 year ago
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(' ');
1 year ago
if(!a.inc[i][j])
putchar('.');
else
1 year ago
putchar(a.inc[i][j] + 48);
putchar(' ');
}
putchar('\n');
}
}
void initRandomSeed(){srand(time(NULL));}
struct Sudoku sudokuRandomGenerate(unsigned int fill){// %
fill %= 101;
1 year ago
struct Sudoku *res = M_Sudoku + tp++;
range81()
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;
1 year ago
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;
}
1 year ago
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){
1 year ago
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){
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;
1 year ago
*x = *y = 0;
range81()
if(!(a->inc[i][j])){
int cnt = 0;
range9(k)
cnt += !((tags->inc[i][j] >> (k+1)) & 1);
if(cnt < minv && cnt != 0)
minv = cnt,
*x = i,
*y = j;
}
}
struct Sudoku *sudokuFill__(struct Sudoku *a, int unfillednum, struct Sudoku *tags){
struct Sudoku *pres, *t_tags;
if(!unfillednum){
1 year ago
pres = M_Sudoku + tp ++;
sudokuCopy(*a, pres);
return pres;
}
int m=0, n=0;
tagFindLeast(a, &m, &n, tags);
range9(i)
1 year ago
if(!((tags->inc[m][n] >> (i+1)) & 1)){
t_tags = M_Sudoku + tp ++;
sudokuCopy(*tags, t_tags);
1 year ago
a->inc[m][n] = i+1;
tagPoint(a, m, n, t_tags);
1 year ago
// 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;
1 year ago
a->inc[m][n] = 0;
tp --;
}
return NULL;
}
struct Sudoku *sudokuFill(struct Sudoku *a){
1 year ago
struct Sudoku tags, res, *pres;
sudokuClear(&tags);
if(tagsInit(a, &tags)) return NULL;
int unfillednum = 0;
1 year ago
range81()
if(!a->inc[i][j])
unfillednum ++;
return sudokuFill__(a, unfillednum, &tags);
1 year ago
}