From ab6efc057229041153b1a942cfa06750b840bb9c Mon Sep 17 00:00:00 2001 From: Nicholas Hope Date: Sat, 10 Sep 2022 14:03:23 -0400 Subject: [PATCH] Works with boilerplate.* --- solvedle.c | 167 +++++++++++++++++------------------------------------ 1 file changed, 53 insertions(+), 114 deletions(-) diff --git a/solvedle.c b/solvedle.c index 83b6fb2..2314a06 100644 --- a/solvedle.c +++ b/solvedle.c @@ -2,42 +2,7 @@ #include #include #include - -#if TIME_SECTIONS - #include - - clock_t start, end; - double section_time, total_time; - char * curr_section; - - #define START_TIME(section_name) do {\ - curr_section = section_name;\ - printf("BEGIN %s\n", curr_section);\ - start = clock();\ - } while (0); - - #define END_TIME do {\ - end = clock();\ - section_time = ((double) (end - start)) / CLOCKS_PER_SEC;\ - printf("END %s: %fs\n\n", curr_section, section_time);\ - total_time += section_time;\ - } while (0); - -#else - // TIME_SECTIONS not specified, define to be nothing - #define START_TIME(section_name) 0; - #define END_TIME 0; - -#endif - -#define WORDS 12971 -#define WORDLEN 5 -#define CHARMASK ~(0b11u << 5u) - -typedef struct signature { - char * word; - uint32_t sign; -} signature; +#include "boilerplate.h" uint32_t rawWC = 0, @@ -45,43 +10,63 @@ uint32_t cookedWC = 0 ; -int compare(const void * a, const void * b) { - return ((signature *)a)->sign - ((signature *)b)->sign; +void findWords(signature* sigs, uint32_t len) { + for (uint32_t i1 = 0; i1 < len; i1++) { + uint32_t a = sigs[i1].sign; + + for (uint32_t i2 = i1+1; i2 < len; i2++) { + uint32_t b = sigs[i2].sign; + if (a & b) { continue; } + uint32_t ab = a | b; + PRINT2 + + for (uint32_t i3 = i2+1; i3 < len; i3++) { + uint32_t c = sigs[i3].sign; + if (ab & c) { continue; } + uint32_t abc = ab | c; + PRINT3 + + for (uint32_t i4 = i3+1; i4 < len; i4++) { + uint32_t d = sigs[i4].sign; + if (abc & d) { continue; } + uint32_t abcd = abc | d; + PRINT4 + + 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); + + #if FIND_ONE + goto loopend; + #endif + + } + } + } + } + } + #if FIND_ONE + loopend: + #endif + return; } signature* rmdups(signature * arr) { // list is already sorted uint32_t nitems = fiveUniqWC; - for (uint32_t i = 0; i < nitems; /* handled in loop */) { - if (arr[i].sign == arr[i + 1].sign) { + for (uint32_t i = 0; i < nitems; i++) { + while (arr[i].sign == arr[i + 1].sign) { memmove( &arr[ i ], &arr[ i + 1 ], (nitems - i) * sizeof(signature)); nitems--; } - else { - i++; - } } cookedWC = nitems; return arr; } -uint32_t getsig(char * word) { - uint32_t result = 0; - for (uint32_t i = 0; i < 5; i++) { - uint32_t bit = 1 << (word[i] & CHARMASK); - if (result & bit) { - // duplicate letters - return 0; - } - result |= bit; - } - return result; -} - 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) { @@ -115,7 +100,7 @@ int main(int argc, char * argv[]) { #if ! ASSUME_SAFE if (f == NULL) { - fprintf(stderr, "%s: %s: no such file or directory\n", argv[0], argv[1]); + fprintf(stderr, "%s, %s, no such file or directory\n", argv[0], argv[1]); return 2; } #endif @@ -123,14 +108,14 @@ int main(int argc, char * argv[]) { START_TIME("making array") signature* sigs = makeArray(f); END_TIME - fclose(f); #if PRINT_INTERMEDIATES - printf("read %u words\n", rawWC); - printf("kept %u words with 5 unique letters\n", fiveUniqWC); + 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 @@ -138,66 +123,20 @@ int main(int argc, char * argv[]) { START_TIME("removing duplicates") sigs = rmdups(sigs); END_TIME +#else + cookedWC = fiveUniqWC; +#endif #if PRINT_INTERMEDIATES - printf("ended with %u totally unique words\n", cookedWC); + fprintf(stderr, "INTERMEDIATE: ended with %u totally unique words\n", cookedWC); #endif START_TIME("finding words") - for (uint32_t i1 = 0; i1 < cookedWC; i1++) { - uint32_t a = sigs[i1].sign; - - for (uint32_t i2 = i1+1; i2 < cookedWC; i2++) { - uint32_t b = sigs[i2].sign; - if (a & b) { - continue; - } - uint32_t ab = a | b; -#if PRINT_INTERMEDIATES - fprintf(stderr, "%s:%s\n", sigs[i1].word, sigs[i2].word); -#endif - - for (uint32_t i3 = i2+1; i3 < cookedWC; i3++) { - uint32_t c = sigs[i3].sign; - if (ab & c) { - continue; - } - uint32_t abc = ab | c; -#if PRINT_INTERMEDIATES - fprintf(stderr, "%s:%s:%s\n", sigs[i1].word, sigs[i2].word, sigs[i3].word); -#endif - - for (uint32_t i4 = i3+1; i4 < cookedWC; i4++) { - uint32_t d = sigs[i4].sign; - if (abc & d) { - continue; - } - uint32_t abcd = abc | d; -#if PRINT_INTERMEDIATES - fprintf(stderr, "%s:%s:%s:%s\n", sigs[i1].word, sigs[i2].word, sigs[i3].word, sigs[i4].word); -#endif - - for (uint32_t i5 = i4+1; i5 < cookedWC; i5++) { - uint32_t e = sigs[i5].sign; - if (abcd & e) { - continue; - } - fprintf(stderr, "%s, %s, %s, %s, %s\n", sigs[i1].word, sigs[i2].word, sigs[i3].word, sigs[i4].word, sigs[i5].word); -#if FIND_ONE - goto loopend; -#endif - } - } - } - } - } -#if FIND_ONE - loopend: -#endif + findWords(sigs, cookedWC); END_TIME #if TIME_SECTIONS clock_t prog_end = clock(); - printf("%s took %fs total\n", argv[0], ((double)(prog_end - prog_start)) / CLOCKS_PER_SEC); + fprintf(stderr, "%s took %fs total\n", argv[0], ((double)(prog_end - prog_start)) / CLOCKS_PER_SEC); #endif return 0;