Run puzzles from file in main()
This commit is contained in:
parent
3d7a40cc58
commit
2ca91dec99
130
main.c
130
main.c
@ -19,110 +19,48 @@
|
|||||||
#include "solve.h"
|
#include "solve.h"
|
||||||
#include "sud.h"
|
#include "sud.h"
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#define PROG_UPDATEPRD 20
|
#define FNAME "puzzles"
|
||||||
#define NPUZZLES 256U
|
#define FSIZE 729000000U
|
||||||
|
#define NSUD (FSIZE / NCELLS)
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
uint32_t seed = getseed();
|
int fd = open(FNAME, O_RDONLY);
|
||||||
printf("Seed: %u\n", seed);
|
if (fd == -1) {
|
||||||
srand(seed);
|
fputs("Failed to open puzzles file\n", stderr);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
struct sudoku puzzles[NPUZZLES];
|
char *buf = mmap(NULL, FSIZE, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||||
struct bench_res res;
|
if (buf == MAP_FAILED)
|
||||||
genpuzzles(puzzles, 0.33, true);
|
fputs("Failed to mmap() puzzle file\n", stderr);
|
||||||
runbench(puzzles, &res);
|
|
||||||
|
|
||||||
puts("\n SUMMARY\n =======");
|
close(fd);
|
||||||
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);
|
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user