Implement check() function to verify solver results

This commit is contained in:
2022-11-23 14:36:45 +00:00
parent 4feaedf1a3
commit 39d417f2bc
2 changed files with 70 additions and 1 deletions

61
sud.c
View File

@@ -171,3 +171,64 @@ void print(const struct sudoku *sud)
putchar('\n');
}
}
static void zerocounts(unsigned counts[NDIGITS])
{
for (unsigned i = 0; i < NDIGITS; ++i)
counts[i] = 0;
}
static bool checkcounts(unsigned counts[NDIGITS])
{
for (unsigned i = 0; i < NDIGITS; ++i) {
if (counts[i] != 1)
return false;
}
return true;
}
enum check_res check(const struct sudoku *sud)
{
unsigned r, c, i, j, digitcounts[NDIGITS];
/* Check each row. */
for (r = 0; r < NDIGITS; ++r) {
zerocounts(digitcounts);
for (c = 0; c < NDIGITS; ++c) {
if (!sud->cells[r][c].det)
return INCOMPLETE;
++digitcounts[sud->cells[r][c].val];
}
if (!checkcounts(digitcounts))
return INCORRECT;
}
/* Check each column. */
for (c = 0; c < NDIGITS; ++c) {
zerocounts(digitcounts);
for (r = 0; r < NDIGITS; ++r) {
if (!sud->cells[r][c].det)
return INCOMPLETE;
++digitcounts[sud->cells[r][c].val];
}
if (!checkcounts(digitcounts))
return INCORRECT;
}
/* Check each segment. */
for (i = 0; i < NDIGITS; ++i) {
zerocounts(digitcounts);
for (j = 0; j < NDIGITS; ++j) {
r = 3 * (i / 3) + j / 3;
c = 3 * (i % 3) + j % 3;
if (!sud->cells[r][c].det)
return INCOMPLETE;
++digitcounts[sud->cells[r][c].val];
}
if (!checkcounts(digitcounts))
return INCORRECT;
}
/* If we've got this far, all is well. */
return SOLVED;
}

10
sud.h
View File

@@ -22,7 +22,7 @@
#include <stdbool.h>
#define SEGLEN 3
#define NDIGITS 9
#define NDIGITS (SEGLEN * SEGLEN)
struct cellstate {
bool det;
@@ -38,6 +38,8 @@ struct sudoku {
enum update_res { NOT_ALLOWED, ALREADY_DET, OK };
enum check_res { INCOMPLETE, INCORRECT, SOLVED };
/**
* Populate the sudoku with some random values.
*/
@@ -57,4 +59,10 @@ update(struct sudoku *sud, unsigned r, unsigned c, unsigned val);
*/
void print(const struct sudoku *sud);
/**
* Determine whether the sudoku has been solved correctly, contains
* invalid choices or is incomplete.
*/
enum check_res check(const struct sudoku *sud);
#endif