diff --git a/main.c b/main.c index cb63b17..9188133 100644 --- a/main.c +++ b/main.c @@ -26,41 +26,47 @@ #include #include -#define FNAME "puzzles" -#define FSIZE 729000000U -#define NSUD (FSIZE / NCELLS) +#define IFNAME "puzzles" +#define OFNAME "results" +#define NSUD 9000000U +#define FSIZE (NSUD * NCELLS) int main(void) { - int fd = open(FNAME, O_RDONLY); + int fd; + + fd = open(IFNAME, O_RDONLY); if (fd == -1) { fputs("Failed to open puzzles file\n", stderr); return EXIT_FAILURE; } + char *ibuf = mmap(NULL, FSIZE, PROT_READ, MAP_PRIVATE, fd, 0); + if (ibuf == MAP_FAILED) { + fputs("Failed to mmap() puzzles file\n", stderr); + return EXIT_FAILURE; + } + close(fd); - char *buf = mmap(NULL, FSIZE, PROT_READ, MAP_PRIVATE, fd, 0); - if (buf == MAP_FAILED) - fputs("Failed to mmap() puzzle file\n", stderr); - + fd = open(OFNAME, O_RDWR); + if (fd == -1) { + fputs("Failed to open results file\n", stderr); + return EXIT_FAILURE; + } + char *obuf = mmap(NULL, FSIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (obuf == MAP_FAILED) { + fputs("Failed to mmap() results file\n", stderr); + return EXIT_FAILURE; + } close(fd); struct sudoku sud; - unsigned solved = 0; - for (unsigned i = 0; i < NSUD; ++i) { - if (!load(&sud, buf + (NCELLS * i))) { - fputs("Failed to load sudoku\n", stderr); - return EXIT_FAILURE; - } - if (solve(&sud) == -1) { - fprintf(stderr, "Solver error on sudoku #%u\n", i); - return EXIT_FAILURE; - } - if (filled(&sud)) - ++solved; + for (unsigned o = 0; o < FSIZE; o += NCELLS) { + load(&sud, ibuf + o); + solve(&sud); + save(&sud, obuf + o); } - double solved_pc = 1e2 * (double)solved / (double)NSUD; - printf("Solved %u/%u (%.3lf%%)\n", solved, NSUD, solved_pc); - + munmap(ibuf, FSIZE); + munmap(obuf, FSIZE); return EXIT_SUCCESS; } diff --git a/sud.c b/sud.c index de70cc0..be0ac41 100644 --- a/sud.c +++ b/sud.c @@ -48,6 +48,18 @@ bool load(struct sudoku *sud, const char *ptr) return true; } +void save(struct sudoku *sud, char *ptr) +{ + for (unsigned r = 0; r < NDIGITS; ++r) { + for (unsigned c = 0; c < NDIGITS; ++c) { + if (DET(sud->cells[r][c])) + *ptr++ = '1' + VAL(sud->cells[r][c]); + else + *ptr++ = '0'; + } + } +} + enum update_res update(struct sudoku *sud, unsigned r, unsigned c, unsigned val) { unsigned tr, tc; diff --git a/sud.h b/sud.h index 0718e9f..e9cf138 100644 --- a/sud.h +++ b/sud.h @@ -47,6 +47,11 @@ enum check_res { INCOMPLETE, INCORRECT, SOLVED }; */ bool load(struct sudoku *sud, const char *ptr); +/** + * Write the sudoku to the given pointer (`NCELLS` bytes). + */ +void save(struct sudoku *sud, char *ptr); + /** * Attempt to update the cell at row `r`, column `c` to have the value * `val`. Returns `OK` on success, `ALREADY_DET` if the cell is