summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Phillips <david@sighup.nz>2019-03-16 22:03:09 +1300
committerDavid Phillips <david@sighup.nz>2019-03-16 22:03:09 +1300
commitc4db7474ffb3454894bc59010e64e3f335fcfa3d (patch)
tree9972b7c0e934307a8eb4c0135f808e3e990bcc9a
parent53e40ead2dc29deaff619803d1aa57812b2920fc (diff)
downloadsudoku-c4db7474ffb3454894bc59010e64e3f335fcfa3d.tar.xz
Don't be strict about solutions
If expected.sku exists, check that the solution matches it, otherwise, just rely on the solution having been some unknown solution, so long as it did not modify the pre-set tiles for the problem, and is a valid and complete sudoku board. This opens up the possibility for testing multi-solution puzzles.
-rwxr-xr-xrun_tests.sh10
-rw-r--r--test-solver.c57
-rw-r--r--test/004-easy/expected.sku11
-rw-r--r--test/004-easy/in.sku11
-rw-r--r--test/100-medium/expected.sku13
-rw-r--r--test/100-medium/in.sku18
6 files changed, 90 insertions, 30 deletions
diff --git a/run_tests.sh b/run_tests.sh
index fe5f068..a5ebb81 100755
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -9,11 +9,12 @@ XFAILS="$PWD/test/xfails"
test_fail() {
t="$(basename $1)"
+ reason="$2"
if grep -q "$t" "$XFAILS" ; then
- echo -e '[\e[34;1mXFAIL\e[0m]'" $t"
+ echo -e '[\e[34;1mXFAIL\e[0m]'" $t: $reason"
((t_xfail++))
else
- echo -e '[\e[31;1mFAIL\e[0m]'" $t"
+ echo -e '[\e[31;1mFAIL\e[0m]'" $t: $reason"
((t_fail++))
fi
}
@@ -26,8 +27,9 @@ test_pass() {
for t in test/*-* ; do
pushd "$t" >/dev/null
- if ! "$SOLVER" >/dev/null ; then
- test_fail "$t"
+ reason="$("$SOLVER" 2>&1 1>/dev/null)"
+ if [ "$?" -ne 0 ]; then
+ test_fail "$t" "$reason"
else
test_pass "$t"
fi
diff --git a/test-solver.c b/test-solver.c
index 4ea14a0..4f5d2ad 100644
--- a/test-solver.c
+++ b/test-solver.c
@@ -1,5 +1,8 @@
#include <stdio.h>
#include <string.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <unistd.h>
#include "debug.h"
#include "update.h"
@@ -8,15 +11,33 @@
#include "display.h"
#include "load.h"
+#define EXPECTED_SKU_FILENAME "./expected.sku"
+
+/* FIXME move to another TU */
+/* Check if all of the non-zero defined cells in *orig are still the same in
+ * *solution */
+int board_subset(struct cell orig[9][9], struct cell solution[9][9])
+{
+ int x = 0;
+ int y = 0;
+
+ for (y = 0; y < 9; y++)
+ for (x = 0; x < 9; x++)
+ if (orig[x][y].val != 0 && orig[x][y].val != solution[x][y].val)
+ return -1;
+
+ return 0;
+}
+
/* FIXME move to another TU */
-int boards_match(struct cell (*lb)[9][9], struct cell (*rb)[9][9])
+int boards_match(struct cell lb[9][9], struct cell rb[9][9])
{
int x = 0;
int y = 0;
for (y = 0; y < 9; y++)
for (x = 0; x < 9; x++)
- if ((*lb)[x][y].val != (*rb)[x][y].val)
+ if (lb[x][y].val != rb[x][y].val)
return -1;
return 0;
@@ -42,6 +63,9 @@ int solve(struct cell (*board)[9][9])
int main(int argc, char **argv)
{
+ int ret = 0;
+ struct stat sb;
+ struct cell orig_board[9][9];
struct cell working_board[9][9];
struct cell correct_board[9][9];
FILE *f = NULL;
@@ -60,9 +84,30 @@ int main(int argc, char **argv)
fclose(f);
+ memcpy(orig_board, working_board, sizeof(orig_board));
+
solve(&working_board);
- if (!(f = fopen("./expected.sku", "r"))) {
+ if (board_subset(orig_board, working_board)) {
+ fprintf(stderr, "Solution has modified one or more starting value(s)!\n");
+ return 1;
+ }
+
+ if (board_is_solved(&working_board)) {
+ fprintf(stderr, "Solution is not valid\n");
+ return 1;
+ }
+
+
+ if (stat(EXPECTED_SKU_FILENAME, &sb) < 0 && errno == ENOENT)
+ return 0;
+
+ /* Extra sanity check if expected.sku is there. Really this isn't needed,
+ * but it's nice to have the sudoku solutions in with the tests for
+ * debugging, so we might as well triple-check the solution against them */
+
+
+ if (!(f = fopen(EXPECTED_SKU_FILENAME, "r"))) {
perror("fopen");
return 1;
}
@@ -74,5 +119,9 @@ int main(int argc, char **argv)
fclose(f);
- return boards_match(&working_board, &correct_board);
+ ret = boards_match(working_board, correct_board);
+ if (ret) {
+ fprintf(stderr, "Solution does not match expected\n");
+ }
+ return ret;
}
diff --git a/test/004-easy/expected.sku b/test/004-easy/expected.sku
new file mode 100644
index 0000000..cb0dea7
--- /dev/null
+++ b/test/004-easy/expected.sku
@@ -0,0 +1,11 @@
+415|789|362
+382|465|197
+967|132|485
+
+153|674|829
+278|951|643
+694|328|571
+
+721|546|938
+536|897|214
+849|213|756
diff --git a/test/004-easy/in.sku b/test/004-easy/in.sku
new file mode 100644
index 0000000..8fc1bdc
--- /dev/null
+++ b/test/004-easy/in.sku
@@ -0,0 +1,11 @@
+???|?89|?6?|
+3??|??5|1?7|
+96?|?3?|4?5|
+
+15?|6??|???|
+??8|9?1|6??|
+???|??8|?71|
+
+7?1|?4?|?38|
+5?6|8??|??4|
+?4?|21?|???|
diff --git a/test/100-medium/expected.sku b/test/100-medium/expected.sku
deleted file mode 100644
index a81eebf..0000000
--- a/test/100-medium/expected.sku
+++ /dev/null
@@ -1,13 +0,0 @@
-?6??5?32?
-?9??4?6??
-7?36?8???
-
-1???7?98?
-6???????2
-?39?8???1
-
-???5?48?7
-??4?3??1?
-?78?6??9?
-
-Needs updating with solution - currently solver cannot solve
diff --git a/test/100-medium/in.sku b/test/100-medium/in.sku
index 03f1055..d4f0032 100644
--- a/test/100-medium/in.sku
+++ b/test/100-medium/in.sku
@@ -1,11 +1,11 @@
-?6??5?32?
-?9??4?6??
-7?36?8???
+?6?|?5?|32?|
+?9?|?4?|6??|
+7?3|6?8|???|
-1???7?98?
-6???????2
-?39?8???1
+1??|?7?|98?|
+6??|???|??2|
+?39|?8?|??1|
-???5?48?7
-??4?3??1?
-?78?6??9?
+???|5?4|8?7|
+??4|?3?|?1?|
+?78|?6?|?9?|