diff options
-rw-r--r-- | README | 8 | ||||
-rw-r--r-- | codeword.c | 120 |
2 files changed, 117 insertions, 11 deletions
@@ -5,7 +5,8 @@ license is available at https://github.com/dwyl/english-words. To use codeword, run it with a text file containing a list of words and a series of arguments that define whether each character position is a missing -letter (using period), a numbered letter or a fixed letter. +letter (using period), a numbered letter or a fixed letter. Also optionally +give it a switch to put it in anagram mode. For instance: @@ -19,3 +20,8 @@ second and fourth character position. To search for a four letter where the third character is 'w' and all other characters can be any letter. + + codeword -a words_alpha.txt k i w i + +To search for anagrams of 'kiwi'. Note that missing letters can also be used +in this mode. Putting in numbers will raise an error. @@ -136,6 +136,80 @@ static int CheckNumbers(const char *buff, const Character *chars, int no_chars) return 1; } +int CheckAnagram(const char *buff, const Character *chars, int no_chars) +{ + size_t l = strlen(buff); + int *used; + int f; + int match; + + if (l != no_chars) + { + return 0; + } + + used = malloc(sizeof *used * no_chars); + + if (!used) + { + Error("malloc"); + } + + for(f = 0; f < no_chars; f++) + { + used[f] = 0; + } + + for(f = 0; f < no_chars; f++) + { + int i; + int found = 0; + + for(i = 0; i < no_chars && !found; i++) + { + if (!used[i] && + chars[i].type == eLetter && + chars[i].letter == buff[f]) + { + used[i] = 1; + found = 1; + } + } + + if (!found) + { + for(i = 0; i < no_chars && !found; i++) + { + if (!used[i] && chars[i].type == eMissing) + { + used[i] = 1; + found = 1; + } + } + } + + if (!found) + { + free(used); + return 0; + } + } + + match = 1; + + for(f = 0; f < no_chars; f++) + { + if (!used[f]) + { + match = 0; + } + } + + free(used); + + return match; +} + int main(int argc, char *argv[]) { int no_chars; @@ -143,15 +217,24 @@ int main(int argc, char *argv[]) int f; FILE *fp; char buff[1024]; + int anagram_mode; + int argc_base = 1; + + if (argc > 1 && strcmp(argv[1], "-a") == 0) + { + anagram_mode = 1; + argc_base = 2; + } - if (argc < 3) + if (argc < 1 + argc_base) { - fprintf(stderr, "usage: %s wordlist <letter, number or period> ...\n", + fprintf(stderr, "usage: %s [-a] wordlist <letter, number " + "or period> ...\n", argv[0]); exit(EXIT_FAILURE); } - no_chars = argc - 2; + no_chars = argc - argc_base - 1; chars = malloc(sizeof *chars * no_chars); if (!chars) @@ -163,12 +246,13 @@ int main(int argc, char *argv[]) { int i; - i = atoi(argv[f+2]); + i = atoi(argv[f + 1 + argc_base]); if (i < 1 || i > 27) { chars[f].type = eLetter; - chars[f].letter = tolower((unsigned char)argv[f+2][0]); + chars[f].letter = + tolower((unsigned char)argv[f + 1 + argc_base][0]); chars[f].number = 0; if (chars[f].letter == '.') @@ -178,27 +262,43 @@ int main(int argc, char *argv[]) } else { + if (anagram_mode) + { + fprintf(stderr, "Can't use numbers in anagram mode\n"); + exit(EXIT_FAILURE); + } + chars[f].type = eNumber; chars[f].number = i; chars[f].letter = 0; } } - fp = fopen(argv[1], "r"); + fp = fopen(argv[argc_base], "r"); if (!fp) { - Error(argv[1]); + Error(argv[argc_base]); } while(fgets(buff, sizeof buff, fp)) { PrepLine(buff); - if (CheckLettersAndLength(buff, chars, no_chars) && - CheckNumbers(buff, chars, no_chars)) + if (anagram_mode) { - printf("%s\n", buff); + if (CheckAnagram(buff, chars, no_chars)) + { + printf("%s\n", buff); + } + } + else + { + if (CheckLettersAndLength(buff, chars, no_chars) && + CheckNumbers(buff, chars, no_chars)) + { + printf("%s\n", buff); + } } } |