feat: add Sudoku Solver LeetCode (#1162)

Co-authored-by: David Leal <halfpacho@gmail.com>
This commit is contained in:
Alexander Pantyukhin 2022-12-21 18:44:43 +04:00 committed by GitHub
parent 0169283f55
commit 9f1591fbd2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 89 additions and 0 deletions

View File

@ -26,6 +26,7 @@
| 29 | [Divide Two Integers](https://leetcode.com/problems/divide-two-integers/) | [C](./src/29.c) | Medium |
| 32 | [Longest Valid Parentheses](https://leetcode.com/problems/longest-valid-parentheses/) | [C](./src/32.c) | Hard |
| 35 | [Search Insert Position](https://leetcode.com/problems/search-insert-position/) | [C](./src/35.c) | Easy |
| 37 | [Sudoku Solver](https://leetcode.com/problems/sudoku-solver/) | [C](./src/37.c) | Hard |
| 38 | [Count and Say](https://leetcode.com/problems/count-and-say/) | [C](./src/38.c) | Easy |
| 42 | [Trapping Rain Water](https://leetcode.com/problems/trapping-rain-water/) | [C](./src/42.c) | Hard |
| 53 | [Maximum Subarray](https://leetcode.com/problems/maximum-subarray/) | [C](./src/53.c) | Easy |

88
leetcode/src/37.c Normal file
View File

@ -0,0 +1,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);
}