You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
2.2 KiB
90 lines
2.2 KiB
#include <stdio.h> |
|
#include <string.h> |
|
#include <stdlib.h> |
|
#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); |
|
} |