#include #include #include #include #include typedef struct { int is_letter; int number; char letter; } Character; static void PrepLine(char *p) { size_t l = strlen(p); size_t f; while (l && p[l-1] == '\n') { p[--l] = 0; } for(f = 0; f < l; f++) { p[f] = tolower((unsigned char)p[f]); } } static void Error(const char *p) { perror(p); exit(EXIT_FAILURE); } static int ContainsLetter(char c, const Character *chars, int no_chars) { int f; for(f=0; f < no_chars; f++) { if (chars[f].is_letter && chars[f].letter == c) { return 1; } } return 0; } static int CheckLettersAndLength(const char *buff, const Character *chars, int no_chars) { size_t l = strlen(buff); int f; if (l != no_chars) { return 0; } for(f=0; f < no_chars; f++) { if (chars[f].is_letter && (chars[f].letter != buff[f])) { return 0; } } return 1; } static int CheckNumbers(const char *buff, const Character *chars, int no_chars) { int f; int n; char code[27] = {0}; for(f = 0; f < no_chars; f++) { if (!chars[f].is_letter) { int i = chars[f].number - 1; if (ContainsLetter(buff[f], chars, no_chars)) { return 0; } if (code[i] && code[i] != buff[f]) { return 0; } for(n = 0; n < 27; n++) { if (n != i && code[n] == buff[f]) { return 0; } } code[i] = buff[f]; } } return 1; } int main(int argc, char *argv[]) { int no_chars; Character *chars; int f; FILE *fp; char buff[1024]; if (argc < 3) { fprintf(stderr, "usage: %s wordlist ...\n", argv[0]); exit(EXIT_FAILURE); } no_chars = argc - 2; chars = malloc(sizeof *chars * no_chars); if (!chars) { Error("malloc"); } for(f = 0; f < no_chars; f++) { int i; i = atoi(argv[f+2]); if (i < 1 || i > 27) { chars[f].is_letter = 1; chars[f].letter = tolower((unsigned char)argv[f+2][0]); chars[f].number = 0; } else { chars[f].is_letter = 0; chars[f].number = i; chars[f].letter = 0; } } fp = fopen(argv[1], "r"); if (!fp) { Error(argv[1]); } while(fgets(buff, sizeof buff, fp)) { PrepLine(buff); if (CheckLettersAndLength(buff, chars, no_chars) && CheckNumbers(buff, chars, no_chars)) { printf("%s\n", buff); } } return EXIT_SUCCESS; }