/*
 *  Given a key word as an argument, print all words from standard input
 *  (assumed to be one word per line) that can be made using the letters
 *  in the key word.  For example,
 *
 *          a.out supercalifragilisticexpialidocious </usr/dict/words
 *
 *  will produce as output a list of 2847 words (many of which aren't
 *  really words, but that's a failing of /u/d/w, not this program).
 *
 *  The heart is "Encode", which transforms a word into an array of ints
 *  representing the number of each letter in the word.  One word can be
 *  made from the letters of another word iff the one word's array is less
 *  than or equal to the other word's array, elementwise.
 *
 *  by Mag, 10 Nov 1992.
 */

#include <stdio.h>

#define MAX_LENGTH 80

void Encode (char*, int*, int);
int LessEqArray (int*, int*, int);

main(int argc, char** argv)
{
   char word[MAX_LENGTH+1];
   int wordcode[128];
   int keycode[128];

   /* check for correct user input */
   if (argc < 2) {
      printf ("No key word given.\n");
      exit (37);
      }
   else if (argc > 2) {
      printf ("Too many arguments.\n");
      exit (37);
      }

   Encode (*(++argv), keycode, 128);

   while ((fgets (word, MAX_LENGTH+1, stdin)) != NULL) {

      /* punt the '\n' that fgets() sticks in the string */
      if (*(word+strlen(word)-1) == '\n')
         *(word+strlen(word)-1) = '\0';

      Encode (word, wordcode, 128);

      if (LessEqArray (wordcode, keycode, 128))
         fprintf (stdout, "%s\n", word);

      }

   exit(0);
}


/*
 * Encode -- Counts the number of each ASCII character in "word".  For
 *           example, code['a'] will be the number of a's in "word".
 */
void Encode (char* word, int* code, int codelength)
{
   int i = 0;
   int* temp = code;
   while (i++ < codelength)             /* initializes "code" */
      *temp++ = 0;
   while (*word)
      (*(code + *word++)) ++;           /* a truly amazing statement */
   return;
}


/*
 * LessEqArray -- Returns TRUE iff "array1" is less than or equal to
 *                "array2" on an element-by-element basis.
 */
int LessEqArray (int* array1, int* array2, int length)
{
   int i = 0, happy = 1;
   while ((i++ < length) && happy)
      happy &= (*(array1++) <= *(array2++));
   return happy;
}

