#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; } uint32_t getsig(char* restrict word) { uint32_t result = 0; for (uint32_t i = 0; i < 5; i++) { uint32_t bit = 1u << (word[i] & CHARMASK); if (result & bit) { // duplicate letters return 0; } result |= bit; } return result; } uint32_t rmdups(signature* restrict arr, uint32_t nitems) { // list is already sorted 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--; } } return nitems; } 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 memcpy(sigs[i].word, word, 5); sigs[i].sign = s; i++; } } *arrlen = i; return sigs; } void printDashed(const uint32_t n) { for (uint32_t i = A_BIT; i < Z_BIT; i <<= 1) { if (i & n) { char c = 'A'; uint32_t bit = A_BIT; while (bit < i) { c++; bit <<= 1; } putchar(c); } else { putchar('-'); } } } void printsigs(signature* restrict 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 : %-4d\n", s.word, index); } putchar('\n'); va_end(args); }