diff --git a/solvedle.c b/solvedle.c index b87a60f..83b6fb2 100644 --- a/solvedle.c +++ b/solvedle.c @@ -3,14 +3,42 @@ #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 { +typedef struct signature { char * word; uint32_t sign; } signature; + uint32_t rawWC = 0, fiveUniqWC = 0, @@ -18,10 +46,10 @@ uint32_t ; int compare(const void * a, const void * b) { - return (((signature *)a)->sign) - (((signature *)b)->sign); + return ((signature *)a)->sign - ((signature *)b)->sign; } -void * rmdups(signature * arr) { +signature* rmdups(signature * arr) { // list is already sorted uint32_t nitems = fiveUniqWC; for (uint32_t i = 0; i < nitems; /* handled in loop */) { @@ -35,7 +63,6 @@ void * rmdups(signature * arr) { } cookedWC = nitems; return arr; - // return realloc(arr, cookedWC * sizeof(signature)); } uint32_t getsig(char * word) { @@ -51,52 +78,71 @@ uint32_t getsig(char * word) { return result; } -void * makeArray(FILE * f) { +signature* makeArray(FILE * f) { signature* sigs = (signature*) calloc(WORDS, sizeof(signature)); char word[WORDLEN + sizeof(char)]; // 5 letters + \n - uint32_t charsRead; 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 realloc(sigs, fiveUniqWC * sizeof(signature)); 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; } - signature* sigs = (signature*) makeArray(f); +#endif + + 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); +#endif + START_TIME("sorting") qsort(sigs, fiveUniqWC, sizeof(signature), compare); - sigs = (signature*) rmdups(sigs); + END_TIME + + START_TIME("removing duplicates") + sigs = rmdups(sigs); + END_TIME + +#if PRINT_INTERMEDIATES printf("ended with %u totally unique words\n", cookedWC); -#if 0 - for (uint32_t i = 0; i < cookedWC; i++) { - printf("%u\n", sigs[i].sign); - } -#else +#endif + START_TIME("finding words") for (uint32_t i1 = 0; i1 < cookedWC; i1++) { uint32_t a = sigs[i1].sign; @@ -106,7 +152,7 @@ int main(int argc, char * argv[]) { continue; } uint32_t ab = a | b; -#if print +#if PRINT_INTERMEDIATES fprintf(stderr, "%s:%s\n", sigs[i1].word, sigs[i2].word); #endif @@ -116,7 +162,7 @@ int main(int argc, char * argv[]) { continue; } uint32_t abc = ab | c; -#if print +#if PRINT_INTERMEDIATES fprintf(stderr, "%s:%s:%s\n", sigs[i1].word, sigs[i2].word, sigs[i3].word); #endif @@ -126,7 +172,7 @@ int main(int argc, char * argv[]) { continue; } uint32_t abcd = abc | d; -#if print +#if PRINT_INTERMEDIATES fprintf(stderr, "%s:%s:%s:%s\n", sigs[i1].word, sigs[i2].word, sigs[i3].word, sigs[i4].word); #endif @@ -136,13 +182,22 @@ int main(int argc, char * argv[]) { continue; } fprintf(stderr, "%s, %s, %s, %s, %s\n", sigs[i1].word, sigs[i2].word, sigs[i3].word, sigs[i4].word, sigs[i5].word); - // goto loopend; +#if FIND_ONE + goto loopend; +#endif } } } } } - // loopend: +#if FIND_ONE + loopend: +#endif + 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); #endif return 0;