_       _       
  (_) ___ | |_ ____
  | |/ _ \| __|_  /
  | | (_) | |_ / / 
 _/ |\___/ \__/___|
|__/               

Pnemonic finder

This is a work in progress.

This program is designed to filter matching strings from a text file containing a dictionary of words, like sowpods.txt.

To compile the program:

gcc -o pnemonicfinder pnemonicfinder.c

To filter a list of words down to a list of matching candidate words, do this:

cat sowpods.txt | pnemonicfinder

The idea is to find words that are anagrams (ish) of a template string (e.g. "m[edr][mi][rc][it]s[tw]rs") in which each sub-list in square brackets provides multiple options for one of the letters. It's an interesting variant on the normal problem of anagram finding. The sub-lists for some letters provide additional options for finding matching words, but it makes the search more complicated. I assume this type of search already has an established name, but I haven't figured out what it is.

I'm using this to help me find words to use as pnemonics in my teaching. Given a list of items to remember, the idea is to choose a word that represents each item, then take the first letter of each word and find a pnemonic that contains all the first letters. In some cases, there may be several words that could represent the item, so there may be several option for the corresponding letter. This program helps to find a word that contains one matching character for each item.

//
// finder.c
//

#include <stdio.h>
#include <string.h>

int main()
{
    char buf[256];
    int n = 0, len, i, badletter;

    while (n < 100)
    {
        scanf("%s", buf);

        if (feof(stdin)) break;
        len = strlen(buf);
        if (len < 9 || len > 9) continue;
        if (!strpbrk(buf, "m")) continue;
        if (!strpbrk(buf, "edr")) continue;
        if (!strpbrk(buf, "mi")) continue;
        if (!strpbrk(buf, "rc")) continue;
        if (!strpbrk(buf, "it")) continue;
        if (!strpbrk(buf, "s")) continue;
        if (!strpbrk(buf, "tw")) continue;
        if (!strpbrk(buf, "r")) continue;
        if (!strpbrk(buf, "s")) continue;

        badletter = 0;
        for (i=0 ; i<9 ; ++i) if (!strchr("medrictsw", buf[i]))
        {
            badletter = 1;
            break;
        }
        if (badletter) continue;

        printf("%d %s\n", n, buf);
        ++n;
    }

    // m[edr][mi][rc][it]s[tw]rs

    return 0;
}