/*
* Copyright (C) 2022 Camden Dixie O'Brien
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this program. If not, see
* .
*/
#include "solve.h"
#include "sud.h"
#include
#include
#include
#include
#define PROG_UPDATEPRD 20
#define NPUZZLES 1024U
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;
}
int main(void)
{
uint32_t seed = getseed();
printf("Seed: %u\n\n", seed);
srand(seed);
struct sudoku puzzles[NPUZZLES];
unsigned i, j, bslen = 0;
fputs("Generating... ", stdout);
for (i = 0; i < NPUZZLES; ++i) {
if (i % PROG_UPDATEPRD == 0) {
for (j = 0; j < bslen; ++j)
putchar('\b');
bslen = (unsigned)printf("%u%%", 100 * i / NPUZZLES);
fflush(stdout);
}
gen(&puzzles[i]);
}
for (j = 0; j < bslen; ++j)
putchar('\b');
puts("100%");
int res[NPUZZLES];
struct timespec start, end;
fputs("Solving... ", stdout);
fflush(stdout);
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);
puts("done");
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;
const double avg_micros = tot_micros / NPUZZLES;
unsigned solved = 0;
unsigned 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];
}
const double succ_rate = (double)solved / NPUZZLES;
const unsigned avg_passes = tot_passes / NPUZZLES;
puts("\n SUMMARY\n =======");
printf("Success rate: %.0lf%%\n", 1e2 * succ_rate);
printf("Average time: %.3lf µs\n", avg_micros);
printf("Average n.o. passes: %u\n", avg_passes);
return 0;
}