/* This program finds words that are anagrams of concatenations of Greek letters. For example, "petunia" is an anagram of "Pi Eta Nu." Public domain, 2005. */ #include #include #include int is_good(const char *word); int letter_cmp(const void *p, const void *q); char *remv(const char *word, const char *letter); int main() { char buffer[1000], word[1000]; while (fgets(word, sizeof word, stdin) != NULL) { int i; for (i=0; isalpha(word[i]); ++i) { word[i] = tolower(word[i]); } word[i] = '\0'; strcpy(buffer, word); qsort(buffer, strlen(buffer), 1, letter_cmp); if (is_good(buffer)) printf("%s\n", word); } return 0; } const char *alph[] = { "aahlp", "abet", "aagmm", "adelt", "eilnops", "aetz", "aet", "aehtt", "aiot", "aakpp", "aabdlm", "mu", "nu", "ix", "cimnoor", "ip", "hor", "agims", "atu", "ilnopsu", "hip", "chi", "ips", "aegmo" }; int letter_cmp(const void *p, const void *q) { char a = *(const char *)p; char b = *(const char *)q; return (a < b)? -1: (a > b); } int is_good(const char *word) { int i; if (word == NULL) return 0; if (*word == '\0') return 1; /* Letters not used in Greek alphabet */ if (strchr(word, 'f')) return 0; if (strchr(word, 'j')) return 0; if (strchr(word, 'q')) return 0; if (strchr(word, 'v')) return 0; if (strchr(word, 'w')) return 0; if (strchr(word, 'y')) return 0; /* Letters used once in Greek alphabet */ if (strchr(word, 'k')) { char *tmp = remv(word, "aakpp"); if (is_good(tmp)) { free(tmp); return 1; } else { free(tmp); return 0; } } if (strchr(word, 'r')) { char *tmp = remv(word, "hor"); if (is_good(tmp)) { free(tmp); return 1; } else { free(tmp); return 0; } } if (strchr(word, 'x')) { char *tmp = remv(word, "ix"); if (is_good(tmp)) { free(tmp); return 1; } else { free(tmp); return 0; } } if (strchr(word, 'z')) { char *tmp = remv(word, "aetz"); if (is_good(tmp)) { free(tmp); return 1; } else { free(tmp); return 0; } } /* Fall back on brute force */ for (i=0; i < sizeof(alph)/sizeof(*alph); ++i) { char *tmp = remv(word, alph[i]); if (is_good(tmp)) { free(tmp); return 1; } else free(tmp); } return 0; } /* word and letter are both sorted */ char *remv(const char *word, const char *letter) { char *buffer = malloc(strlen(word)+1); const char *p = word, *q = letter; char *b = buffer; while (*p != '\0') { if (*q && (*q < *p)) { free(buffer); return NULL; } else if (*q && (*q == *p)) { ++q; ++p; continue; } else *b++ = *p++; } if (*q != '\0') { free(buffer); return NULL; } *b = '\0'; return buffer; }