summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README8
-rw-r--r--codeword.c120
2 files changed, 117 insertions, 11 deletions
diff --git a/README b/README
index 7beedac..d8e4a6a 100644
--- a/README
+++ b/README
@@ -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.
diff --git a/codeword.c b/codeword.c
index fc68f3a..4080c7f 100644
--- a/codeword.c
+++ b/codeword.c
@@ -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);
+ }
}
}