99 lines
2.4 KiB
C
99 lines
2.4 KiB
C
/*
|
|
* 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
|
|
* <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "solve.h"
|
|
#include "sud.h"
|
|
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
|
|
#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%");
|
|
|
|
bool 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;
|
|
for (i = 0; i < NPUZZLES; ++i) {
|
|
if (res[i] && check(&puzzles[i]) == SOLVED)
|
|
++solved;
|
|
}
|
|
|
|
puts("\n SUMMARY\n =======");
|
|
printf("Success rate: %.0lf%%\n", 1e2 * (double)solved / NPUZZLES);
|
|
printf("Average time: %.3lf µs\n", avg_micros);
|
|
|
|
return 0;
|
|
}
|