-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
/
Copy path37.c
88 lines (72 loc) · 3.1 KB
/
37.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
int** initSet(int size){
int** result = (int**) malloc(size * sizeof(int*));
for (int i = 0; i < size; i++) {
result[i] = (int*)calloc(size, sizeof(int));
}
return result;
}
// Returns the id of triplet which the point (i, j) belongs to
int getTripletId(int i, int j){
return (i / 3) * 3 + (j / 3);
}
// Recursive function which populates sudoku board.
bool sudokuSolver(int startI, int startJ, char** board, int boardSize, int* boardColSize, int** horizontalsSets, int** verticalsSets, int** tripletsSets){
for (int i = startI; i < boardSize; i++) {
for (int j = startJ; j < boardColSize[i]; j++) {
if (board[i][j] != '.'){
continue;
}
// Find the sets of the current point (i, j)
int* horizontalSet = horizontalsSets[i];
int* verticalSet = verticalsSets[j];
int* tripletsSet = tripletsSets[getTripletId(i, j)];
for (int z = 1; z < 10; z++) {
if (horizontalSet[z] || verticalSet[z] || tripletsSet[z]){
continue;
}
// If the z doesn't belong to occupations sets, we check this value to be in place
horizontalSet[z] = 1;
verticalSet[z] = 1;
tripletsSet[z] = 1;
if (sudokuSolver(i, j + 1, board, boardSize, boardColSize, horizontalsSets, verticalsSets, tripletsSets)){
board[i][j] = z + '0';
return true;
}
horizontalSet[z] = 0;
verticalSet[z] = 0;
tripletsSet[z] = 0;
}
// We tried all possible values in range 1-10. No variants - returns false;
return false;
}
// startJ to begin of the row.
startJ = 0;
}
// Reach it when the end of the board - then all previous values are setup correctly.
return true;
}
// Use backtracking
void solveSudoku(char** board, int boardSize, int* boardColSize){
// Declare sets for cheking occupation of numbers by horizontals, verticals lines and triplets.
int** horizontalsSets = initSet(boardSize + 1);
int** verticalsSets = initSet(boardSize + 1);
int** tripletsSets = initSet(getTripletId(boardSize + 1, boardSize + 1));
// Populate sets with values from the board.
for (int i = 0; i < boardSize; i++) {
for (int j = 0; j < boardColSize[i]; j++) {
if (board[i][j] == '.'){
continue;
}
int value = board[i][j] - '0';
horizontalsSets[i][value] = 1;
verticalsSets[j][value] = 1;
tripletsSets[getTripletId(i, j)][value] = 1;
}
}
// Solving
sudokuSolver(0, 0, board, boardSize, boardColSize, horizontalsSets, verticalsSets, tripletsSets);
// Free resources
free(horizontalsSets);
free(verticalsSets);
free(tripletsSets);
}