From: "M. Leo Cooper" <thegrendel@theriver.com>
Newsgroups: alt.sources
Subject: anagram ( source/Unix )
Date: Sat, 22 Nov 1997 22:37:45 -0700
Organization: All USENET -- http://www.Supernews.com
Message-ID: <Pine.LNX.3.91.971122223523.292A-100000@thegrendel.theriver.com>

Followup-To: thegrendel@theriver.com

Submitted-by: thegrendel@theriver.com
Archive-name: anagram/part01

#!/bin/sh
# This is anagram, a shell archive (produced by GNU sharutils 4.1)
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 1997-11-22 18:37 MST by <thegrendel@theriver.com>.
# Source directory was `/home/thegrendel/alt.tst'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode       name
# ------ ---------- ------------------------------------------
#   1654 -rw-r--r-- README
#    469 -rw-r--r-- Makefile
#    443 -rw-r--r-- srch.h
#   4661 -rw-r--r-- anagram.c
#
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
  shar_touch=touch
else
  shar_touch=:
  echo
  echo 'WARNING: not restoring timestamps.  Consider getting and'
  echo "installing GNU \`touch', distributed in GNU File Utilities..."
  echo
fi
rm -f 1231235999 $$.touch
#
# ============= README ==============
if test -f 'README' && test X"$1" != X"-c"; then
  echo 'x - skipping README (file already exists)'
else
  echo 'x - extracting README (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'README' &&
X                           Anagram
X
X
This anagramming program can provide the core of a list generating
package and/or study system for word game players, particularly devotees
of that notorious board game, Scrabble (TM). As a stand alone program,
"anagram" generates a list of all anagrams that can be generated from an
input letter set. For example, the letter set "test" has the following
anagrams:
X       es
X       et
X       set
X       sett
X       stet
X       test
X       tet
X       tets
X
The invocation syntax is "anagram letter_set [word_file]". To anagram
"test", as above, anagram test. Unless a word file is specified as the
argument after letter_set, a default word file named word.lst is
assumed. Any word file in the "standard" ASCII, one word per line
format, should work.
X
It is highly recommended that users of this program obtain the
word.lst file from the free Public Domain "ENABLE" word list package.
X             This list archive can be downloaded at
X       http://personal.riverusers.com/~thegrendel/enable10.zip.
The list is in DOS format, so you should remove those nasty CR's from
the end of each entry with a "dos2unix" utility.
X
Like any well behaved Unix utility, anagram writes its output to STDOUT.
The anagrams are listed one per line, with "bingos" (words with 7 or
more letters for those of you who are not word gamers) prefixed by an
asterisk.
X
If there is sufficient interest shown, I will post the source to my
*multiple word* anagram utility, for finding anagrams such as "find this
word" in the letter set "ddfhiinorstw".
X
---
Scrabble is a trademark of the Milton Bradley Co., In.
X
X
X
X
M\Cooper
thegrendel@theriver.com
http://personal.riverusers.com/~thegrendel/
SHAR_EOF
  $shar_touch -am 1122183697 'README' &&
  chmod 0644 'README' ||
  echo 'restore of README failed'
  shar_count="`wc -c < 'README'`"
  test 1654 -eq "$shar_count" ||
    echo "README: original size 1654, current size $shar_count"
fi
# ============= Makefile ==============
if test -f 'Makefile' && test X"$1" != X"-c"; then
  echo 'x - skipping Makefile (file already exists)'
else
  echo 'x - extracting Makefile (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
#                        Makefile for "anagram"
#
# M\Cooper
# PO Box 237
# St. David, AZ 85630-0237
# E-mail: thegrendel@theriver.com
# Web   http://personal.riverusers.com/~thegrendel/
X
CC = gcc
# If you don't have gnu gcc then change the above line to
# CC = cc
X
anagram : anagram.c srch.h
X       $(CC) -O2 -fomit-frame-pointer -m386 -o anagram anagram.c
# If you don't have gnu gcc, change above line to
#       $(CC) anagram.c
#       Poor fellow, no optimization.
X
clean :
X       rm *.o
SHAR_EOF
  $shar_touch -am 1122174797 'Makefile' &&
  chmod 0644 'Makefile' ||
  echo 'restore of Makefile failed'
  shar_count="`wc -c < 'Makefile'`"
  test 469 -eq "$shar_count" ||
    echo "Makefile: original size 469, current size $shar_count"
fi
# ============= srch.h ==============
if test -f 'srch.h' && test X"$1" != X"-c"; then
  echo 'x - skipping srch.h (file already exists)'
else
  echo 'x - extracting srch.h (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'srch.h' &&
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
X
#define COMPARISON_ERROR 1
#define MAXTESTS 50
#define MAX_WLEN 24
#define MAX_SPAN 25
X
const char Wordfile[] = "word.lst";
X
typedef enum { FAIL, SUCCESS } Rflag;
X
/*********************PROTOTYPES***********************************/
Rflag l_search( char *search_word, FILE *fp );
Rflag b_search( char *search_word, FILE *fp, long left, long right );
Rflag lookup( char *test_word );
SHAR_EOF
  $shar_touch -am 1122172697 'srch.h' &&
  chmod 0644 'srch.h' ||
  echo 'restore of srch.h failed'
  shar_count="`wc -c < 'srch.h'`"
  test 443 -eq "$shar_count" ||
    echo "srch.h: original size 443, current size $shar_count"
fi
# ============= anagram.c ==============
if test -f 'anagram.c' && test X"$1" != X"-c"; then
  echo 'x - skipping anagram.c (file already exists)'
else
  echo 'x - extracting anagram.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'anagram.c' &&
/**************************************************************************/
/*                                 Anagram Utility                        */
/*                                                                        */
/*                                     M\Cooper                           */
/*                                    PO Box 237                          */
/*                            St. David, AZ 85630-0237                    */
/*                        -------------------------------                 */
/*                        Email:  thegrendel@theriver.com                 */
/*                Web: http://personal.riverusers.com/~thegrendel         */
/*                                                                        */
/*                                                                        */
/**************************************************************************/
X
X
#include "srch.h"
X
X
#define FILE_OPENING_ERROR 3
#define FILENAME_MAXLEN 8
#define CR "\n"
#define FILE_SUFFIX ".ana"
#define MAXLEN 40
#define LINE_LEN 80
#define NOARGS 1
#define INCREMENT 1
#define BINGOLEN 8
#define SPACE ' '
#define XOUT '@'
#define WILDCARD '_'
#define FILLCHAR '_'
#define ASTERISK "*"
#define WD 12
X
#define BUFFERSIZE 8192
X
X   char ad[] =
"ANAGRAM utility by M\\Cooper, PO Box 237, St. David, AZ 85630-0237";
X
typedef enum { FALSE, TRUE } Boolean;
X
void getword( char *lset, char *filename );
void center( char *strng );
Boolean isanagram( char *letterset, char *word );
X
X
void main( int argc, char **argv )
{
X
X   char letterset[ MAXLEN ],
X        filename[ MAXLEN ];
X
X
X        if( argc == NOARGS )
X           {
X           puts("Enter a LETTERSET to test ... ");
X           gets( letterset );
X           }
X        else
X           strcpy( letterset, *( argv + 1 ) );
X
X
X         if( argc == NOARGS + 2 )
X            strcpy( filename, *( argv + 2 ) );
X         else
X            strcpy( filename, Wordfile );
X
X        getword( letterset, filename );
}
X
X
/**********************************ISANAGRAM*******************************/
/*       Function tests if word is constructible from Letterset           */
/*                 Args in: char *letterset, char *word                   */
/*   Returns: error_flag == TRUE (1) if constructible, FALSE (0) if not   */
/**************************************************************************/
X
Boolean isanagram( char *letterset, char *word )
{
X       Boolean error_flag = TRUE;
X       static char dup_lset[ MAXLEN ];
X       register char *letpos;
X
X        strcpy( dup_lset, letterset );
X         strcat( dup_lset, "\n" );
X
X               while( *word )
X                       {
X                       if( ( letpos  = strchr( dup_lset, *word++ ) ) != NULL )
X                               *letpos = XOUT;
X      else
X         if( ( letpos = strchr( dup_lset, WILDCARD ) ) != NULL )
X            *letpos = XOUT;
X
X                       else
X                               { error_flag = FALSE; break; }
X                       }
X
X               return( error_flag );
}
X
/*************************************************************/
void getword( char *letter_set, char *fname )
{
X
X       char    l_set [ MAXLEN ],
X               word [ MAXLEN ],
X                asterisk [ MAXLEN ],
X               tempstr [ MAXLEN + 1 ],
X               targetfile [ MAXLEN ],
X                msg [ WD ],
X                *ppos;
X
X       FILE *fptr,
X               *tfile;
X       int fnamelen,
X     i;
X       long wcount = 0L;
X
X
X
X          strcpy ( l_set, letter_set );
X
X          /*********************************************************/
X
X          if( !( fptr = fopen( fname, "rt" ) ) )
X                {
X                printf( "\7\7\7Cannot open Wordfile!" );
X                exit( FILE_OPENING_ERROR );
X                }
X      if( setvbuf( fptr, NULL, _IOFBF, BUFFERSIZE * 2 ) )
X         exit ( FILE_OPENING_ERROR );  /*Extra buffering.*/
X
X
X
X
X
X                /*********************Main Loop*************/
X                 while( fgets( word, MAXLEN, fptr ) != NULL )
X
X                       if( isanagram( letter_set, word ) )
X                          {
X                           if( strlen( word ) >= BINGOLEN )
X                               {
X                               strcpy( asterisk, ASTERISK );
X                               strcat( asterisk, word );
X                               strcpy( word, asterisk );
X                               }
X                          printf( "%s", word );
X                          wcount++;
X                          }
X                 /*******************************************/
X
X
X
X
X
/***************************for MSDOG**********************
X
X      if( wcount == INCREMENT )
X          strcpy( msg, "word" );
X      else
X          strcpy( msg, "words" );
X
X                 printf( "%ld %s can be anagrammed from %s.\n",
X                                wcount, msg, l_set );
*************************************************************/
X
X
}
X
X
X
void center( char *str )
{
X   int padding;
X   char st [ LINE_LEN + INCREMENT ];
X
X        padding = LINE_LEN / 2 - strlen( str ) / 2;
X        memset( st, SPACE, padding );
X        *( st + padding ) = 0;
X        strcat( st, str );
X        strcpy( str, st );
X
X        return;
}
SHAR_EOF
  $shar_touch -am 1122172697 'anagram.c' &&
  chmod 0644 'anagram.c' ||
  echo 'restore of anagram.c failed'
  shar_count="`wc -c < 'anagram.c'`"
  test 4661 -eq "$shar_count" ||
    echo "anagram.c: original size 4661, current size $shar_count"
fi
exit 0



