From demon!bnr.co.uk!zaphod.axion.bt.co.uk!marble.uknet.ac.uk!mcsun!uunet!elroy.jpl.nasa.gov!usc!howland.reston.ans.net!sol.ctr.columbia.edu!eff!news.oc.com!convex!tchrist Fri Apr  2 18:16:24 GMT 1993
Article: 953 of alt.sources
Newsgroups: alt.sources
Path: demon!bnr.co.uk!zaphod.axion.bt.co.uk!marble.uknet.ac.uk!mcsun!uunet!elroy.jpl.nasa.gov!usc!howland.reston.ans.net!sol.ctr.columbia.edu!eff!news.oc.com!convex!tchrist
From: Tom Christiansen <tchrist@convex.COM>
Subject: yet another anagram program
Originator: tchrist@pixel.convex.com
Sender: usenet@news.eng.convex.com (news access account)
Message-ID: <1993Apr3.133356.22030@news.eng.convex.com>
Date: Sat, 3 Apr 1993 13:33:56 GMT
Reply-To: tchrist@convex.COM (Tom Christiansen)
Nntp-Posting-Host: pixel.convex.com
Organization: minimal
X-Disclaimer: This message was written by a user at CONVEX Computer
              Corp. The opinions expressed are those of the user and
              not necessarily those of CONVEX.
Lines: 398

$ echo some phrase | anagram -p

There's extra dreck at the end of little throwaway helper programs that I
probably don't even remember what do anymore.

--tom

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	anagram.c
#	cuddle.pl
#	getwords
#	max
#	shuffle
#	uchange
# This archive created: Sat Apr  3 07:27:49 1993
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'anagram.c'" '(3701 characters)'
if test -f 'anagram.c'
then
	echo shar: "will not over-write existing file 'anagram.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'anagram.c'
	X#include <stdio.h>
	X#include <ctype.h>
	X#include <sysexits.h>
	X#include <signal.h>
	X#include <setjmp.h>
	X
	X#define INPUT "/usr/dict/words"
	X
	X#define COUNT ('z' - 'a' + 2)
	X#define  EOW   ('z' - 'a' + 1)
	X
	Xstruct dict_level {
	X    struct dict_level *ltr[COUNT];
	X} Table; 
	X
	Xstruct letterpad {
	X    int count;
	X    char ltr[COUNT];
	X};
	X
	Xjmp_buf Prompt_Env;
	X
	Xchar Line[100];
	Xchar Word[100];
	Xchar *Letter;
	X
	Xlong long Word_Count = 0;
	Xlong long Allocated = 0;
	Xlong long Slots;
	X
	Xint Debug = 0;
	Xint Phrase_Mode;
	Xint Max_Idx;
	Xchar *Program;
	X
	X
	Xint from_a_tty, to_a_tty;
	X
	Xint fetch(), interrupt();
	X
	Xmain(ac, av)
	X    char **av;
	X{
	X    FILE *fp;
	X    char *input;
	X    struct dict_level *dp;
	X
	X    from_a_tty = isatty(0);
	X    to_a_tty   = isatty(1);
	X
	X    Program = *av;
	X
	X    if (ac > 4) 
	X	usage(Program);
	X
	X    if (ac == 3) {
	X	if (strcmp(av[1], "-p"))
	X	    usage();
	X	ac--; av++;
	X	if (ac == 1) 
	X	    usage();
	X	Phrase_Mode = 1;
	X    } 
	X
	X    Max_Idx = Phrase_Mode ? COUNT : EOW;
	X    input = ac == 2 ? av[1] : INPUT;
	X
	X    if (!(fp = fopen(input, "r"))) {
	X	perror(input);
	X	exit(EX_NOINPUT);
	X    } 
	X
	X    setlinebuf(stdout, 0);
	X
	X    while ( fgets(Line, sizeof(Line), fp) ) {
	X	Word_Count++;
	X	if (Debug) printf("storing %s", Line);
	X	store(Line);
	X    }
	X
	X    *(Letter = Word) = '\0';
	X
	X    {
	X	long long slotmax = Allocated * 26;
	X
	X	dump(&Table);
	X	fprintf(stderr, "%lld Words, %lld levels\n", Word_Count, Allocated);
	X	fprintf(stderr, "%lld/%lld pointers used (%4.1f%%)\n", 
	X			Slots, slotmax, 
	X			100 * ((double)Slots)/((double)slotmax));
	X    }
	X
	X
	X
	X    signal(SIGINT, interrupt);
	X
	X    while (1) {
	X	setjmp(Prompt_Env);
	X	if (from_a_tty) 
	X	    printf("> ");
	X	if (!gets(Line))
	X	    break;
	X	anagram(Line);
	X    }
	X
	X    exit(EX_OK);
	X}
	X
	Xstore (s)
	X    char *s;
	X{
	X    struct dict_level *dp = &Table;
	X    char a,*cp;
	X
	X    for (cp = s; *cp && *cp != '\n'; cp++) {
	X	if (isupper(*cp))
	X	    *cp = tolower(*cp);
	X	if (*cp < 'a' || *cp > 'z') 
	X	    return;
	X	a = *cp - 'a';
	X	if (!dp->ltr[a]) {
	X	    if (!(dp->ltr[a] = (struct dict_level *) 
	X				calloc(1, sizeof(struct dict_level)))) 
	X	    {
	X		perror("calloc");
	X		exit(EX_OSERR);
	X	    } 
	X	    Allocated++;
	X	}
	X	dp = dp->ltr[a];
	X    } 
	X    dp->ltr[EOW] = (struct dict_level *) -1;
	X} 
	X
	Xdump(dp)
	X    struct dict_level *dp;
	X{
	X    char digit;
	X
	X    if (!dp) {
	X	fprintf(stderr, "can't get here!!!\n");
	X	return;
	X    } 
	X
	X    for (digit = 0; digit < COUNT; digit++) {
	X	if (dp->ltr[digit]) {
	X	    Slots++;
	X	    if (digit == EOW) {
	X		if (Debug) printf("Word! %s\n", Word);
	X		*--Letter = '\0';
	X		return;
	X	    } 
	X	    *Letter = digit + 'a';
	X	    *++Letter = '\0';
	X	    dump(dp->ltr[digit]);
	X	} 
	X    } 
	X    *--Letter = '\0';
	X    
	X} 
	X
	Xanagram(s)
	X    char *s;
	X{
	X    struct letterpad master;
	X    int i;
	X    char *cp;
	X
	X    for (i = 0; i < 26; i++) 
	X	master.ltr[i] = 0;
	X
	X    master.count = 0;
	X
	X    for (cp = s; *cp; cp++) {
	X	if (isupper(*cp))
	X	    *cp = tolower(*cp);
	X	if (*cp < 'a' || *cp > 'z') 
	X	    continue;
	X	master.count++;
	X	master.ltr[*cp - 'a']++;
	X    } 
	X
	X    *(Letter = Word) = '\0';
	X
	X    fetch(&Table, &master); 
	X} 
	X
	Xfetch (tp, pp)
	X    struct dict_level *tp;
	X    struct letterpad  *pp;
	X{
	X    int i;
	X
	X    if (pp->count == 0) {
	X	if (tp->ltr[EOW] && strcmp(Line,Word)) {
	X	    printf("%s: %s\n", Line, Word);
	X	    return 1;
	X	} 
	X	return 0;
	X    } 
	X
	X    for (i = 0; i < Max_Idx; i++) {
	X	if (pp->ltr[i] && tp->ltr[i]) {
	X	    if (Phrase_Mode && i == EOW) {
	X		*Letter++ = ' ';
	X		fetch(&Table, pp);
	X	    } else {
	X		*Letter++ = i + 'a';
	X		pp->ltr[i]--;
	X		pp->count--;
	X		fetch(tp->ltr[i], pp);
	X		pp->ltr[i]++;
	X		pp->count++;
	X	    }
	X	    *--Letter = '\0';
	X	} 
	X    } 
	X    return 0;
	X} 
	X
	Xusage () 
	X{
	X    fprintf(stderr, "usage: %s [-p] [dictionary]\n", Program);
	X    exit(EX_USAGE);
	X} 
	X
	Xinterrupt() {
	X    printf("\n");
	X    longjmp(Prompt_Env);
	X} 
SHAR_EOF
if test 3701 -ne "`wc -c < 'anagram.c'`"
then
	echo shar: "error transmitting 'anagram.c'" '(should have been 3701 characters)'
fi
chmod 644 'anagram.c'
fi
echo shar: "extracting 'cuddle.pl'" '(428 characters)'
if test -f 'cuddle.pl'
then
	echo shar: "will not over-write existing file 'cuddle.pl'"
else
sed 's/^	X//' << \SHAR_EOF > 'cuddle.pl'
	X#!/usr/bin/perl
	X
	X$| = 1;
	X
	Xwhile (<>) {
	X    ($orig, $perm) = split;
	X    next unless $perm;
	X    if ($orig ne $old) {
	X	&output($old, $aliases);
	X	$aliases = '';
	X    } 
	X    $old = $orig;
	X    $aliases .= "$perm ";
	X} 
	X
	X&output($old, $aliases);
	X
	Xsub output {
	X    return unless $_[0];
	X    return if $seen{$_[0]};
	X    local(@strings) = split(' ',"@_");
	X    for (@strings) {
	X	$seen{$_}++;
	X	printf ("%-13s ", $_);
	X    } 
	X    print "\n";
	X} 
SHAR_EOF
if test 428 -ne "`wc -c < 'cuddle.pl'`"
then
	echo shar: "error transmitting 'cuddle.pl'" '(should have been 428 characters)'
fi
chmod 764 'cuddle.pl'
fi
echo shar: "extracting 'getwords'" '(71 characters)'
if test -f 'getwords'
then
	echo shar: "will not over-write existing file 'getwords'"
else
sed 's/^	X//' << \SHAR_EOF > 'getwords'
	X#!/usr/bin/perl
	X
	Xwhile (<>) {
	X} 
	X    next if /^[^aio]$/;
	X    print;
	X} 
SHAR_EOF
if test 71 -ne "`wc -c < 'getwords'`"
then
	echo shar: "error transmitting 'getwords'" '(should have been 71 characters)'
fi
chmod 664 'getwords'
fi
echo shar: "extracting 'max'" '(161 characters)'
if test -f 'max'
then
	echo shar: "will not over-write existing file 'max'"
else
sed 's/^	X//' << \SHAR_EOF > 'max'
	X#!/usr/bin/perl
	X
	Xwhile (<>)  {
	X    split;
	X    #print if $#_ > 2;
	X    if ($#_ >= $count) {
	X	print;
	X	$count = $#_;
	X	$line = $_;
	X    } 
	X} 
	Xprint "\n";
	Xprint $line;
SHAR_EOF
if test 161 -ne "`wc -c < 'max'`"
then
	echo shar: "error transmitting 'max'" '(should have been 161 characters)'
fi
chmod 664 'max'
fi
echo shar: "extracting 'shuffle'" '(89 characters)'
if test -f 'shuffle'
then
	echo shar: "will not over-write existing file 'shuffle'"
else
sed 's/^	X//' << \SHAR_EOF > 'shuffle'
	X#!/usr/bin/perl
	X
	Xsrand;
	X@lines = <>;
	Xprint splice(@lines, rand(@lines), 1) while @lines;
SHAR_EOF
if test 89 -ne "`wc -c < 'shuffle'`"
then
	echo shar: "error transmitting 'shuffle'" '(should have been 89 characters)'
fi
chmod 775 'shuffle'
fi
echo shar: "extracting 'uchange'" '(164 characters)'
if test -f 'uchange'
then
	echo shar: "will not over-write existing file 'uchange'"
else
sed 's/^	X//' << \SHAR_EOF > 'uchange'
	X#!/usr/bin/perl
	X
	Xwhile (<>) {
	X    $u_words{$_} ++ if /u/;
	X    push(@w_words, $_) if /w/;
	X} 
	X
	Xwhile ($_ = pop @w_words) {
	X    s/w/u/g;
	X    print if $u_words{$_};
	X} 
SHAR_EOF
if test 164 -ne "`wc -c < 'uchange'`"
then
	echo shar: "error transmitting 'uchange'" '(should have been 164 characters)'
fi
chmod 664 'uchange'
fi
exit 0
#	End of shell archive
-- 
    Tom Christiansen      tchrist@convex.com      convex!tchrist
As far as the laws of mathematics refer to reality, they are not
certain; and as far as they are certain, they do not refer to reality.
                --Albert Einstein


