diff --git a/Makefile b/Makefile index 17817e2..526feef 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ .POSIX: -CFLAGS += -std=c11 -pedantic -Wall -Wextra +CFLAGS += -std=c89 -pedantic -Wall -Wextra CFLAGS += -O3 -flto CFLAGS += -D_XOPEN_SOURCE=700 CFLAGS += -march=native diff --git a/eval.c b/eval.c index 19cdd48..45fb7dc 100644 --- a/eval.c +++ b/eval.c @@ -28,21 +28,25 @@ int main(void) { - FILE *rfp = fopen(RESNAME, "rb"); + FILE *rfp, *sfp; + unsigned solved = 0, errors = 0, i, j; + char res[NCELLS], sol[NCELLS]; + int allcells; + double pc; + + rfp = fopen(RESNAME, "rb"); if (!rfp) { fputs("Failed to open results file\n", stderr); return EXIT_FAILURE; } - FILE *sfp = fopen(SOLNAME, "rb"); + sfp = fopen(SOLNAME, "rb"); if (!sfp) { fputs("Failed to open solutions file\n", stderr); return EXIT_FAILURE; } - unsigned solved = 0, errors = 0; - char res[NCELLS], sol[NCELLS]; - for (unsigned i = 0; i < NPUZZ; ++i) { + for (i = 0; i < NPUZZ; ++i) { if (fread(&res, sizeof(char), NCELLS, rfp) != NCELLS) { fprintf(stderr, "Failed to read result #%u\n", i); return EXIT_FAILURE; @@ -52,10 +56,10 @@ int main(void) return EXIT_FAILURE; } - bool allcells = true; - for (unsigned j = 0; j < NCELLS; ++j) { + allcells = 1; + for (j = 0; j < NCELLS; ++j) { if (res[j] != sol[j]) { - allcells = false; + allcells = 0; if (res[j] != '0') ++errors; } @@ -64,7 +68,7 @@ int main(void) ++solved; } - double pc = 1e2 * (double)solved / (double)NPUZZ; + pc = 1e2 * (double)solved / (double)NPUZZ; printf("%u/%u (%.2f%%) solved, %u errors\n", solved, NPUZZ, pc, errors); fclose(rfp); diff --git a/genlut.c b/genlut.c index 968203f..4f91eb5 100644 --- a/genlut.c +++ b/genlut.c @@ -25,10 +25,11 @@ static void prlut(const char *name, unsigned lut[NCELLS][NDIGITS - 1]) { + unsigned i, j; printf("const unsigned %s[NCELLS][NDIGITS - 1] = {\n", name); - for (unsigned i = 0; i < NCELLS; ++i) { - printf("\t[%2u] = { ", i); - for (unsigned j = 0; j < NDIGITS - 1; ++j) { + for (i = 0; i < NCELLS; ++i) { + fputs("\t{ ", stdout); + for (j = 0; j < NDIGITS - 1; ++j) { printf("%2u", lut[i][j]); if (j != NDIGITS - 2) putchar(','); @@ -44,14 +45,14 @@ int main(void) unsigned rowidx_lut[NCELLS][NDIGITS - 1]; unsigned colidx_lut[NCELLS][NDIGITS - 1]; unsigned segidx_lut[NCELLS][NDIGITS - 1]; + unsigned rowi, coli, segi, r, c, i, j, sr, sc; /* Populate tables. */ - unsigned rowi, coli, segi; - for (unsigned r = 0; r < NDIGITS; ++r) { - for (unsigned c = 0; c < NDIGITS; ++c) { + for (r = 0; r < NDIGITS; ++r) { + for (c = 0; c < NDIGITS; ++c) { /* Calculate row and column indices. */ rowi = coli = 0; - for (unsigned i = 0; i < NDIGITS; ++i) { + for (i = 0; i < NDIGITS; ++i) { if (i != c) rowidx_lut[r * NDIGITS + c][rowi++] = r * NDIGITS + i; if (i != r) @@ -60,10 +61,10 @@ int main(void) /* Calculate segment indices. */ segi = 0; - const unsigned sr = SEGLEN * (r / SEGLEN); - const unsigned sc = SEGLEN * (c / SEGLEN); - for (unsigned i = sr; i < sr + SEGLEN; ++i) { - for (unsigned j = sc; j < sc + SEGLEN; ++j) { + sr = SEGLEN * (r / SEGLEN); + sc = SEGLEN * (c / SEGLEN); + for (i = sr; i < sr + SEGLEN; ++i) { + for (j = sc; j < sc + SEGLEN; ++j) { if (i == r && j == c) continue; segidx_lut[r * NDIGITS + c][segi++] = i * NDIGITS + j; diff --git a/main.c b/main.c index 78e0884..afeb0a9 100644 --- a/main.c +++ b/main.c @@ -41,12 +41,12 @@ static char *obuf; void *threadproc(void *arg) { - unsigned start = CELLPT * (uintptr_t)arg; + unsigned start = CELLPT * (uintptr_t)arg, o; const char *libuf = ibuf + start; char *lobuf = obuf + start; - struct sudoku sud; - for (unsigned o = 0; o < CELLPT; o += NCELLS) { + + for (o = 0; o < CELLPT; o += NCELLS) { load(&sud, libuf + o); solve(&sud); save(&sud, lobuf + o); @@ -58,6 +58,8 @@ void *threadproc(void *arg) int main(void) { int fd; + pthread_t pool[NTHREADS]; + uintptr_t i; fd = open(IFNAME, O_RDONLY); if (fd == -1) { @@ -83,8 +85,6 @@ int main(void) } close(fd); - pthread_t pool[NTHREADS]; - uintptr_t i; for (i = 0; i < NTHREADS; ++i) { if (pthread_create(&pool[i], NULL, threadproc, (void *)i) != 0) fprintf(stderr, "Failed to create thread #%lu\n", i); diff --git a/solve.c b/solve.c index c1fc7f0..2399ba2 100644 --- a/solve.c +++ b/solve.c @@ -23,7 +23,8 @@ static void setpval(struct sudoku *sud, unsigned i, uint16_t pval) { - for (unsigned val = 0; val < NDIGITS; ++val) { + unsigned val; + for (val = 0; val < NDIGITS; ++val) { if (pval & 1) { update(sud, i, val); return; @@ -35,11 +36,11 @@ static void setpval(struct sudoku *sud, unsigned i, uint16_t pval) int solve(struct sudoku *sud) { unsigned n, i, j, val; - bool match; + int match; uint16_t valmask, pvals; for (n = 0;; ++n) { - match = false; + match = 0; for (i = 0; i < NCELLS; ++i) { if (DET(sud->cells[i])) @@ -54,7 +55,7 @@ int solve(struct sudoku *sud) if (pvals & 1) { if (pvals == 1) { update(sud, i, val); - match = true; + match = 1; goto next_cell; } break; @@ -71,7 +72,7 @@ int solve(struct sudoku *sud) valmask |= sud->cells[rowidx_lut[i][j]]; if ((pvals = sud->cells[i] & ~valmask)) { setpval(sud, i, pvals); - match = true; + match = 1; continue; } @@ -84,7 +85,7 @@ int solve(struct sudoku *sud) valmask |= sud->cells[colidx_lut[i][j]]; if ((pvals = sud->cells[i] & ~valmask)) { setpval(sud, i, pvals); - match = true; + match = 1; continue; } @@ -97,7 +98,7 @@ int solve(struct sudoku *sud) valmask |= sud->cells[segidx_lut[i][j]]; if ((pvals = sud->cells[i] & ~valmask)) { setpval(sud, i, pvals); - match = true; + match = 1; continue; } diff --git a/sud.c b/sud.c index 70d41bf..26113d0 100644 --- a/sud.c +++ b/sud.c @@ -16,8 +16,8 @@ * . */ -#include "lut.h" #include "sud.h" +#include "lut.h" #include #include @@ -28,28 +28,31 @@ static void init(struct sudoku *sud) { - for (unsigned i = 0; i < NCELLS; ++i) + unsigned i; + for (i = 0; i < NCELLS; ++i) sud->cells[i] = CELLINIT; } -bool load(struct sudoku *sud, const char *ptr) +int load(struct sudoku *sud, const char *ptr) { + unsigned i; init(sud); - for (unsigned i = 0; i < NCELLS; ++i) { + for (i = 0; i < NCELLS; ++i) { if (ptr[i] == '0') continue; if (update(sud, i, ptr[i] - '1') != OK) - return false; + return 0; } - return true; + return 1; } void save(struct sudoku *sud, char *ptr) { - for (unsigned i = 0; i < NCELLS; ++i) { + unsigned i; + for (i = 0; i < NCELLS; ++i) { if (DET(sud->cells[i])) *ptr++ = '1' + VAL(sud->cells[i]); else @@ -60,10 +63,11 @@ void save(struct sudoku *sud, char *ptr) enum update_res update(struct sudoku *sud, unsigned i, unsigned val) { const uint16_t clearmask = ~(1 << val); + unsigned j; /* Update possible values of cells in same row, column and * segment. */ - for (unsigned j = 0; j < NGROUP; ++j) { + for (j = 0; j < NGROUP; ++j) { sud->cells[rowidx_lut[i][j]] &= clearmask; sud->cells[colidx_lut[i][j]] &= clearmask; sud->cells[segidx_lut[i][j]] &= clearmask; @@ -79,7 +83,9 @@ enum update_res update(struct sudoku *sud, unsigned i, unsigned val) void print(const struct sudoku *sud) { - for (unsigned r = 0; r < NDIGITS; ++r) { + unsigned r, c; + + for (r = 0; r < NDIGITS; ++r) { /* * Print horizontal divider if on a segment boundary (but not * at the start). @@ -87,7 +93,7 @@ void print(const struct sudoku *sud) if (r != 0 && r % SEGLEN == 0) puts("------+-------+------"); - for (unsigned c = 0; c < NDIGITS; ++c) { + for (c = 0; c < NDIGITS; ++c) { /* * Print vertical divider if on a segment boundary (but * not at the start). @@ -106,17 +112,19 @@ void print(const struct sudoku *sud) static void zerocounts(unsigned counts[NDIGITS]) { - for (unsigned i = 0; i < NDIGITS; ++i) + unsigned i; + for (i = 0; i < NDIGITS; ++i) counts[i] = 0; } -static bool checkcounts(unsigned counts[NDIGITS]) +static int checkcounts(unsigned counts[NDIGITS]) { - for (unsigned i = 0; i < NDIGITS; ++i) { + unsigned i; + for (i = 0; i < NDIGITS; ++i) { if (counts[i] != 1) - return false; + return 0; } - return true; + return 1; } enum check_res check(const struct sudoku *sud) @@ -165,13 +173,14 @@ enum check_res check(const struct sudoku *sud) return SOLVED; } -bool filled(const struct sudoku *sud) +int filled(const struct sudoku *sud) { - for (unsigned r = 0; r < NDIGITS; ++r) { - for (unsigned c = 0; c < NDIGITS; ++c) { + unsigned r, c; + for (r = 0; r < NDIGITS; ++r) { + for (c = 0; c < NDIGITS; ++c) { if (!(DET(sud->cells[IDX(r, c)]))) - return false; + return 0; } } - return true; + return 1; } diff --git a/sud.h b/sud.h index d11f411..08b28d3 100644 --- a/sud.h +++ b/sud.h @@ -19,7 +19,6 @@ #ifndef SUD_H #define SUD_H -#include #include #define SEGLEN 3 @@ -48,7 +47,7 @@ enum check_res { INCOMPLETE, INCORRECT, SOLVED }; * Read `NCELLS` values from the given pointer and load them into the * sudoku. */ -bool load(struct sudoku *sud, const char *ptr); +int load(struct sudoku *sud, const char *ptr); /** * Write the sudoku to the given pointer (`NCELLS` bytes). @@ -75,6 +74,6 @@ enum check_res check(const struct sudoku *sud); /** * Determine whether all the sudoku's cells have been determined. */ -bool filled(const struct sudoku *sud); +int filled(const struct sudoku *sud); #endif