sudoku: solver: add single occurence heuristic
This commit is contained in:
parent
0fcee5bc0c
commit
18bb94836e
|
@ -11,6 +11,7 @@ project(
|
|||
sources = [
|
||||
'src/constraints.c',
|
||||
'src/main.c',
|
||||
'src/solver/single_occurence.c',
|
||||
'src/solver/solve.c',
|
||||
'src/solver/update_sets.c',
|
||||
'src/sudoku.c',
|
||||
|
|
|
@ -6,5 +6,6 @@
|
|||
struct sudoku;
|
||||
|
||||
bool update_sets(const struct sudoku *grid, bool possibilities[9][9][9]);
|
||||
bool single_occurrence(struct sudoku *grid, bool possibilities[9][9][9]);
|
||||
|
||||
#endif /* !INTERNALS_H */
|
||||
|
|
92
src/solver/single_occurence.c
Normal file
92
src/solver/single_occurence.c
Normal file
|
@ -0,0 +1,92 @@
|
|||
#include "internals.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "sudoku.h"
|
||||
|
||||
static bool single_line(struct sudoku *grid, bool possibilities[9][9][9],
|
||||
size_t i, size_t j) {
|
||||
for (int n = 0; n < 9; ++n) {
|
||||
if (!possibilities[i][j][n])
|
||||
continue;
|
||||
|
||||
bool unique = true;
|
||||
for (size_t c = 0; c < 9; ++c) {
|
||||
if (c == j)
|
||||
continue;
|
||||
unique &= !possibilities[i][c][n];
|
||||
}
|
||||
if (!unique)
|
||||
continue;
|
||||
|
||||
grid->grid[i][j] = n + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool single_column(struct sudoku *grid, bool possibilities[9][9][9],
|
||||
size_t i, size_t j) {
|
||||
for (int n = 0; n < 9; ++n) {
|
||||
if (!possibilities[i][j][n])
|
||||
continue;
|
||||
|
||||
bool unique = true;
|
||||
for (size_t l = 0; l < 9; ++l) {
|
||||
if (l == i)
|
||||
continue;
|
||||
unique &= !possibilities[l][j][n];
|
||||
}
|
||||
if (!unique)
|
||||
continue;
|
||||
|
||||
grid->grid[i][j] = n + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool single_square(struct sudoku *grid, bool possibilities[9][9][9],
|
||||
size_t i, size_t j) {
|
||||
const size_t x = i / 3;
|
||||
const size_t y = j / 3;
|
||||
|
||||
for (int n = 0; n < 9; ++n) {
|
||||
if (!possibilities[i][j][n])
|
||||
continue;
|
||||
|
||||
bool unique = true;
|
||||
for (size_t l = 3 * x; l < 3 * (x + 1); ++l) {
|
||||
for (size_t c = 3 * y; c < 3 * (y + 1); ++c) {
|
||||
if ((l == i) && (c == j))
|
||||
continue;
|
||||
unique &= !possibilities[i][c][n];
|
||||
}
|
||||
}
|
||||
if (!unique)
|
||||
continue;
|
||||
|
||||
grid->grid[i][j] = n + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool single_occurrence(struct sudoku *grid, bool possibilities[9][9][9]) {
|
||||
bool changed = false;
|
||||
|
||||
for (size_t i = 0; i < 9; ++i) {
|
||||
for (size_t j = 0; j < 9; ++j) {
|
||||
if (grid->grid[i][j] != 0)
|
||||
continue;
|
||||
changed |= single_line(grid, possibilities, i, j)
|
||||
|| single_column(grid, possibilities, i, j)
|
||||
|| single_square(grid, possibilities, i, j);
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
|
@ -28,6 +28,7 @@ bool solve(struct sudoku *grid) {
|
|||
changed = false;
|
||||
|
||||
changed |= update_sets(grid, possibilities);
|
||||
changed |= single_occurrence(grid, possibilities);
|
||||
} while (changed);
|
||||
|
||||
return solved(grid);
|
||||
|
|
Loading…
Reference in a new issue