diff --git a/boilerplate.c b/boilerplate.c index 42c7f40..c056a5d 100644 --- a/boilerplate.c +++ b/boilerplate.c @@ -1,7 +1,12 @@ #include #include +#include #include "boilerplate.h" +#if PRINT_INTERMEDIATES +extern uint32_t rawWC; +#endif + int compare(const void * a, const void * b) { return ((signature *)a)->sign - ((signature *)b)->sign; } @@ -28,4 +33,57 @@ uint32_t rmdups(signature * arr, uint32_t nitems) { } } return nitems; +} + +void printDashed(uint32_t n) { + for (uint32_t i = A_BIT; i < Z_BIT; i <<= 1) { + if (i & n) { + char c = 'A'; + uint32_t icopy = A_BIT; + while (icopy < i) { + c++; + icopy <<=1 ; + } + putchar(c); + } else { + putchar('-'); + } + } +} + +void printsigs(signature* sigs, uint32_t nitems, ...) { + va_list args; + va_start(args, nitems); + + for (uint32_t i = 0; i < nitems; i++) { + uint32_t index = va_arg(args, uint32_t); + signature s = sigs[index]; + printDashed(s.sign); + printf(": %s : %04d\n", s.word, index); + } + + va_end(args); +} + +signature* makeArray(FILE * f, uint32_t* arrlen) { + signature* sigs = (signature*) calloc(WORDS, sizeof(signature)); + char word[WORDLEN + sizeof(char)]; // 5 letters + \n + uint32_t i = 0; + + while (fread(word, sizeof(char), WORDLEN + sizeof(char), f) != 0) { + #if PRINT_INTERMEDIATES + rawWC++; + #endif + // only get sign so far, more efficient + uint32_t s = getsig(word); + if (s != 0) { + // no duplicate word letters in word + sigs[i].word = strndup(word, 5); + sigs[i].sign = s; + i++; + } + } + + *arrlen = i; + return sigs; } \ No newline at end of file diff --git a/boilerplate.h b/boilerplate.h index e822a31..d064c08 100644 --- a/boilerplate.h +++ b/boilerplate.h @@ -1,4 +1,9 @@ #include +#include + +#if PRINT_INTERMEDIATES +uint32_t rawWC = 0; +#endif #if TIME_SECTIONS #include @@ -27,25 +32,17 @@ #endif /* */ - #define WORDS 12971 - #define WORDLEN 5 + #define WORDS 12971u + #define WORDLEN 5u #define CHARMASK ~0b1100000u - - #define A_BIT 0b10 - #define B_BIT 0b100 - #define C_BIT 0b1000 - #define D_BIT 0b10000 + #define A_BIT 0b10u + #define Z_BIT (A_BIT << 26) #if PRINT_INTERMEDIATES - #define PRINT2\ - printf("%s, %s\n", sigs[i1].word, sigs[i2].word); - - #define PRINT3\ - printf("%s, %s, %s\n", sigs[i1].word, sigs[i2].word, sigs[i3].word); - - #define PRINT4\ - printf("%s, %s, %s, %s\n", sigs[i1].word, sigs[i2].word, sigs[i3].word, sigs[i4].word); + #define PRINT2 printsigs(sigs, 2, i1, i2); + #define PRINT3 printsigs(sigs, 3, i1, i2, i3); + #define PRINT4 printsigs(sigs, 4, i1, i2, i3, i4); #else #define PRINT2 0; #define PRINT3 0; @@ -59,10 +56,13 @@ typedef struct signature { } signature; /* */ - int compare(const void*, const void*); - + signature* makeArray(FILE *, uint32_t*); uint32_t getsig(char*); - void findWords(signature*, uint32_t); + int compare(const void*, const void*); uint32_t rmdups(signature*, uint32_t); + + void findWords(signature*, uint32_t); + void printsigs(signature*, uint32_t, ...); + void printDashed(uint32_t); /* */ diff --git a/solvedle.c b/solvedle.c index 109f654..73f65e9 100644 --- a/solvedle.c +++ b/solvedle.c @@ -4,12 +4,71 @@ #include #include "boilerplate.h" -uint32_t - rawWC, - fiveUniqWC -; +#if PRINT_INTERMEDIATES +extern uint32_t rawWC; +#endif + +int main(int argc, char * argv[]) { + #if TIME_SECTIONS + clock_t prog_start = clock(); + #endif + + FILE * f; + + #if ASSUME_SAFE + if (argc != 2) { + fprintf(stderr, "usage: %s file\n", argv[0]); + return 2; + } + f = fopen(argv[1], "r"); + if (f == NULL) { + fprintf(stderr, "%s: %s: no such file or directory\n", argv[0], argv[1]); + return 2; + } + #else + f = fopen(argv[1], "r"); + #endif + + START_TIME("making array") + uint32_t fiveUniqWC; + signature* sigs = makeArray(f, &fiveUniqWC); + END_TIME + fclose(f); + + #if PRINT_INTERMEDIATES + fprintf(stderr, "INTERMEDIATE: read %u words\n", rawWC); + fprintf(stderr, "INTERMEDIATE: kept %u words with 5 unique letters\n", i); + #endif + + #if DELETE + START_TIME("sorting") + qsort(sigs, fiveUniqWC, sizeof(signature), compare); + END_TIME + + START_TIME("removing duplicates") + uint32_t cookedWC = rmdups(sigs, fiveUniqWC); + END_TIME + #else + uint32_t cookedWC = fiveUniqWC; + #endif + + #if PRINT_INTERMEDIATES + fprintf(stderr, "INTERMEDIATE: ended with %u totally unique words\n", cookedWC); + #endif + START_TIME("finding words") + findWords(sigs, cookedWC); + END_TIME + + #if TIME_SECTIONS + clock_t prog_end = clock(); + fprintf(stderr, "%s took %fs total\n", argv[0], ((double)(prog_end - prog_start)) / CLOCKS_PER_SEC); + #endif + + return 0; +} void findWords(signature* sigs, uint32_t len) { + for (uint32_t i1 = 0; i1 < len; i1++) { uint32_t a = sigs[i1].sign; @@ -34,7 +93,7 @@ void findWords(signature* sigs, uint32_t len) { for (uint32_t i5 = i4+1; i5 < len; i5++) { uint32_t e = sigs[i5].sign; if (abcd & e) { continue; } - printf("%s, %s, %s, %s, %s\n", sigs[i1].word, sigs[i2].word, sigs[i3].word, sigs[i4].word, sigs[i5].word); + printsigs(sigs, 5, i1, i2, i3, i4, i5); #if FIND_ONE goto loopend; @@ -49,81 +108,4 @@ void findWords(signature* sigs, uint32_t len) { loopend: #endif return; -} - -signature* makeArray(FILE * f) { - signature* sigs = (signature*) calloc(WORDS, sizeof(signature)); - char word[WORDLEN + sizeof(char)]; // 5 letters + \n - - while (fread(word, sizeof(char), WORDLEN + sizeof(char), f) != 0) { - rawWC++; - // only assign sign so far, more efficient - uint32_t s = getsig(word); - if (s != 0) { - // no duplicate word letters in word - sigs[fiveUniqWC].word = strndup(word, 5); - sigs[fiveUniqWC].sign = s; - fiveUniqWC++; - } - } - - return sigs; -} - -int main(int argc, char * argv[]) { -#if TIME_SECTIONS - clock_t prog_start = clock(); -#endif - -#if ! ASSUME_SAFE - if (argc != 2) { - fprintf(stderr, "usage: %s file\n", argv[0]); - return 2; - } -#endif - - FILE * f = fopen(argv[1], "r"); - -#if ! ASSUME_SAFE - if (f == NULL) { - fprintf(stderr, "%s, %s, no such file or directory\n", argv[0], argv[1]); - return 2; - } -#endif - - START_TIME("making array") - signature* sigs = makeArray(f); - END_TIME - fclose(f); - -#if PRINT_INTERMEDIATES - fprintf(stderr, "INTERMEDIATE: read %u words\n", rawWC); - fprintf(stderr, "INTERMEDIATE: kept %u words with 5 unique letters\n", fiveUniqWC); -#endif - -#if DELETE - START_TIME("sorting") - qsort(sigs, fiveUniqWC, sizeof(signature), compare); - END_TIME - - START_TIME("removing duplicates") - uint32_t cookedWC = rmdups(sigs, fiveUniqWC); - END_TIME -#else - uint32_t cookedWC = fiveUniqWC; -#endif - -#if PRINT_INTERMEDIATES - fprintf(stderr, "INTERMEDIATE: ended with %u totally unique words\n", cookedWC); -#endif - START_TIME("finding words") - findWords(sigs, cookedWC); - END_TIME - -#if TIME_SECTIONS - clock_t prog_end = clock(); - fprintf(stderr, "%s took %fs total\n", argv[0], ((double)(prog_end - prog_start)) / CLOCKS_PER_SEC); -#endif - - return 0; } \ No newline at end of file