#include #include #include #include #include #include "debug.h" #include "update.h" #include "cell.h" #include "solve.h" #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 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) return -1; return 0; } /* FIXME move to another TU, dedup with solver.c */ int solve(struct cell (*board)[9][9]) { int i = 0; int total_changes = 0; int change_count = -1; /* 9*9 is worst case */ for (i = 0; i < 9*9 && change_count; i++) { change_count = 0; update_not_row_col(board); change_count += not_to_val_cell(board); change_count += solve_row_col(board); change_count += cells_fill_certainties(board); total_changes += change_count; } return total_changes; } 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; memset(working_board, 0, sizeof(working_board)); if (!(f = fopen("./in.sku", "r"))) { perror("fopen"); return 1; } if (load(f, &working_board) < 0) { fclose(f); return 1; } fclose(f); memcpy(orig_board, working_board, sizeof(orig_board)); solve(&working_board); 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; } if (load(f, &correct_board) < 0) { fclose(f); return 1; } fclose(f); ret = boards_match(working_board, correct_board); if (ret) { fprintf(stderr, "Solution does not match expected\n"); } return ret; }