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 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 X#include X#include X#include X#include 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