mirror of
https://github.com/TheAlgorithms/C
synced 2024-11-25 06:49:36 +03:00
feat: add Sudoku Solver LeetCode (#1162)
Co-authored-by: David Leal <halfpacho@gmail.com>
This commit is contained in:
parent
0169283f55
commit
9f1591fbd2
@ -26,6 +26,7 @@
|
|||||||
| 29 | [Divide Two Integers](https://leetcode.com/problems/divide-two-integers/) | [C](./src/29.c) | Medium |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 53 | [Maximum Subarray](https://leetcode.com/problems/maximum-subarray/) | [C](./src/53.c) | Easy |
|
||||||
|
88
leetcode/src/37.c
Normal file
88
leetcode/src/37.c
Normal 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);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user