From 2ca91dec99e75384a2c4caf4f9c80f57b5fd8004 Mon Sep 17 00:00:00 2001 From: Camden Dixie O'Brien Date: Wed, 23 Nov 2022 22:31:58 +0000 Subject: [PATCH] Run puzzles from file in main() --- main.c | 130 +++++++++++++++------------------------------------------ 1 file changed, 34 insertions(+), 96 deletions(-) diff --git a/main.c b/main.c index 0930242..3eefe3c 100644 --- a/main.c +++ b/main.c @@ -19,110 +19,48 @@ #include "solve.h" #include "sud.h" +#include #include #include #include -#include +#include +#include -#define PROG_UPDATEPRD 20 -#define NPUZZLES 256U - -struct bench_res { - double succ_rate; - double avg_time_us; - double avg_passes; -}; - -static uint32_t getseed(void) -{ - FILE *urandom = fopen("/dev/urandom", "rb"); - if (urandom == NULL) - fprintf(stderr, "Failed to open /dev/urandom\n"); - - uint32_t seed = 0; - for (unsigned i = 0; i < 4; ++i) - seed = seed << 8 | fgetc(urandom); - - fclose(urandom); - - return seed; -} - -static void genpuzzles(struct sudoku puzzles_out[NPUZZLES], - double fill_prop, - bool print_progress) -{ - unsigned i, j, bslen = 0; - - if (print_progress) - fputs("Generating... ", stdout); - - for (i = 0; i < NPUZZLES; ++i) { - if (print_progress && i % PROG_UPDATEPRD == 0) { - for (j = 0; j < bslen; ++j) - putchar('\b'); - bslen = (unsigned)printf("%u%%", 100 * i / NPUZZLES); - fflush(stdout); - } - - gen(&puzzles_out[i], fill_prop); - } - - if (print_progress) { - for (i = 0; i < bslen; ++i) - putchar('\b'); - puts("100%"); - } -} - -static void runbench(struct sudoku puzzles[NPUZZLES], struct bench_res *res_out) -{ - int res[NPUZZLES]; - unsigned i; - struct timespec start, end; - - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); - for (i = 0; i < NPUZZLES; ++i) - res[i] = solve(&puzzles[i]); - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end); - - long secs = end.tv_sec - start.tv_sec; - long nanos = end.tv_nsec - start.tv_nsec; - if (nanos < 0) { - --secs; - nanos += 1000000000; - } - const double tot_micros = 1e6 * (double)secs + (double)nanos / 1e3; - - unsigned solved = 0, tot_passes = 0; - for (i = 0; i < NPUZZLES; ++i) { - if (res[i] < 0) - continue; - if (check(&puzzles[i]) == SOLVED) - ++solved; - tot_passes += (unsigned long)res[i]; - } - - res_out->succ_rate = (double)solved / NPUZZLES; - res_out->avg_time_us = tot_micros / NPUZZLES; - res_out->avg_passes = (double)tot_passes / NPUZZLES; -} +#define FNAME "puzzles" +#define FSIZE 729000000U +#define NSUD (FSIZE / NCELLS) int main(void) { - uint32_t seed = getseed(); - printf("Seed: %u\n", seed); - srand(seed); + int fd = open(FNAME, O_RDONLY); + if (fd == -1) { + fputs("Failed to open puzzles file\n", stderr); + return EXIT_FAILURE; + } - struct sudoku puzzles[NPUZZLES]; - struct bench_res res; - genpuzzles(puzzles, 0.33, true); - runbench(puzzles, &res); + char *buf = mmap(NULL, FSIZE, PROT_READ, MAP_PRIVATE, fd, 0); + if (buf == MAP_FAILED) + fputs("Failed to mmap() puzzle file\n", stderr); - puts("\n SUMMARY\n ======="); - printf("Success rate: %.0lf%%\n", 1e2 * res.succ_rate); - printf("Average time: %.3lf µs\n", res.avg_time_us); - printf("Average n.o. passes: %0.3lf\n", res.avg_passes); + close(fd); - return 0; + 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; + } + + double solved_pc = 1e2 * (double)solved / NSUD; + printf("Solved %u/%u (%.3lf%%)\n", solved, NSUD, solved_pc); + + return EXIT_SUCCESS; }