From: spl@szechuan.ucsd.edu (Steve Lamont)
Newsgroups: alt.slack
Subject: Re: A Message From Jehova 1..
Date: 26 Jan 93 16:36:10 GMT
Organization: University of Calif., San Diego/Microscopy and Imaging Resource
NNTP-Posting-Host: szechuan.ucsd.edu

In article <C1G3rF.F64@unix.amherst.edu> mcspinks@unix.amherst.edu (Snarfblat) writes:
>Can someone send me the source also? can it be FTP'd? if not, it should. 
>The Barney story is a brilliant piece of work. I showed it to a few people
>(no header or sig, just the prose). the response: aside from the boring ones
>who were repulsed and didn't finish reading it, the ones who had opinions all
>thought it was a piece of erotic literature. they cited things liked "fat 
>purple fuck" and "i'm going to tie you up". So, Mr Lamont, is it ok with you 
>if I submit it to Amherst's literary magazine? I won't put your name on it 
>unless you want me to. 

Sure.  Send me a copy when it comes out.

Here's discord, a hack I wrote while waiting for some friends to show
up to go eat Chinese food.  It's pretty ugly in places (well, actually
pretty much everywhere).  If you don't have gcc, change the Makefile
appropriately.

		 - - - - gnaw on dotted line - - - -
#!/bin/sh
# shar:	Shell Archiver  (v1.22)
#
#	Run the following text with /bin/sh to create:
#	  Makefile
#	  discord.c
#
sed 's/^X//' << 'SHAR_EOF' > Makefile &&
X# Released upon the public domain.
X
XCC	= gcc
XOPT	= -O2
XDEBUG	= -g
XFNORD	=
XCFLAGS	= $(OPT) $(DEBUG) $(FNORD)
XLFLAGS	=
X
Xdiscord:	discord.c
X	$(CC) $(CFLAGS) -o discord discord.c $(LFLAGS)
SHAR_EOF
chmod 0644 Makefile || echo "restore of Makefile fails"
sed 's/^X//' << 'SHAR_EOF' > discord.c &&
X#include <stdio.h>
X#include <string.h>
X#include <ctype.h>
X#include <sys/types.h>
X#include <sys/time.h>
X
X/*
X * Copyright?  Hell, if asked, I'll deny I even wrote this bit of trash.
X */
X
Xtypedef struct Words {
X    char *word;
X    int visited;
X    int nfollows;
X    int *counts;
X    int class;
X    struct Words **follows;
X    struct Words *before;
X    struct Words *after;
X} Words;
X
Xenum { FullStop, Punct, Word };
X
Xchar *fetchWord();
XWords *addWord( Words **, char * );
XWords *newWord( char * );
Xvoid erisify( Words *, long, long );
Xvoid setup();
Xvoid tally( Words *, Words * );
Xvoid search( long, Words * );
XWords *chase( Words *, long * );
Xvoid fsort( Words * );
XWords *findNewWord( Words * );
X
Xint wordcount = 0;
X
Xint tgrid[128] = { 0 };
XFILE *f;
X
Xint main( int argc, char **argv )
X
X{
X
X    char *word;
X    Words *w = ( Words *) NULL;
X    Words *last;
X
X    setup();
X
X    last = addWord( &w, fetchWord() );
X    while ( word = fetchWord() ) {
X
X	Words *wd;
X
X	wd = addWord( &w, word );
X	tally( last, wd );
X	last = wd;
X
X    }	
X
X    srandom( ( int ) time( ( time_t *) NULL ) );
X
X    erisify( w, ( random() % 10 ) + 1, random() % wordcount );
X
X    exit( 0 );
X
X}
X
Xvoid setup()
X
X{
X
X    tgrid['@'] = 1;
X    tgrid['#'] = 1;
X    tgrid['$'] = 1;
X    tgrid['%'] = 1;
X    tgrid['^'] = 1;
X    tgrid['&'] = 1;
X    tgrid['*'] = 1;
X    tgrid['('] = 1;
X    tgrid[')'] = 1;
X    tgrid['_'] = 1;
X    tgrid['-'] = 1;
X    tgrid['='] = 1;
X    tgrid['+'] = 1;
X    tgrid['|'] = 1;
X    tgrid['\\'] = 1;
X    tgrid['`'] = 1;
X    tgrid['~'] = 1;
X    tgrid['['] = 1;
X    tgrid[']'] = 1;
X    tgrid['{'] = 1;
X    tgrid['}'] = 1;
X    tgrid[':'] = 1;
X    tgrid[';'] = 1;
X    tgrid['\"'] = 1;
X    tgrid['<'] = 1;
X    tgrid['>'] = 1;
X    tgrid['/'] = 1;
X
X}
X
Xchar *fetchWord()
X
X{
X
X    static char text[30];
X    int ch;
X    int tp = 1;
X    char *txt;
X
X    while ( ( ( ch = getchar() ) != EOF ) && 
X	    ( ( isspace( ch ) || 
X	        isdigit( ch ) ||
X	        tgrid[ch] ) ) )
X	;
X
X    if ( ch != EOF ) {
X
X	text[0] = ch;
X	if ( !ispunct( ch ) ) {
X
X	    while ( ( ( isalnum( text[tp] = getchar() ) ) ||
X		     ( text[tp] == '\'' ) ) && ( tp < 30 ) )
X		tp++;
X		
X	    if ( ( text[0] != 'M' ) || 
X		 ( text[1] != 'r' ) ||
X		 ( text[2] != '.' ) )
X		ungetc( text[tp], stdin );
X	    else
X		tp++;
X
X	}
X	
X	text[tp] = '\0';
X	
X	txt = text;
X
X    } else
X	txt = ( char *) NULL;
X
X    return txt;
X
X}
X
XWords *addWord( Words **w, char *word )
X
X{
X
X    Words *nw;
X
X    if ( !*w )
X	*w = nw = newWord( word );
X    else {
X
X	int s = strcmp( ( *w )->word, word );
X
X	if ( s < 0 )
X	    nw = addWord( &( *w )->after, word );
X	else if ( s > 0 )
X	    nw = addWord( &( *w )->before, word );
X	else
X	    nw = *w;
X
X    }
X
X    return nw;
X
X}
X
XWords *newWord( char *word )
X
X{
X
X    static int left = 0;
X    static Words *w;
X    
X    wordcount++;
X    if ( !left )
X	w = ( Words *) calloc( sizeof( Words ), left = 32768 );
X
X    left--;
X    ( w + left )->word = strdup( word );
X    switch ( *word ) {
X
X      case '!':
X      case '?':
X      case '.': {
X
X	  ( w + left )->class = FullStop;
X	  break;
X
X      }
X      default: {
X
X	  ( w + left )->class = ispunct( *word ) ? Punct : Word;
X	  break;
X
X      }
X
X    }
X
X    return ( w + left );
X
X}
X
Xvoid tally( Words *last, Words *wd )
X
X{
X
X    int i;
X
X    for ( i = 0; i < last->nfollows; i++ )
X	if ( strcmp( last->follows[i]->word, wd->word ) == 0 ) {
X
X	    ( *( last->counts + i ) )++;
X	    return;
X
X	}
X
X    if ( last->nfollows ) {
X
X	last->follows = ( Words **) realloc( last->follows, sizeof( Words *) *
X					    ( last->nfollows + 1 ) );
X	
X	last->counts = ( int *) realloc( last->counts, sizeof( int ) *
X					( last->nfollows + 1 ) );
X	
X    } else {
X
X	last->follows = ( Words **) malloc( sizeof( Words *) *
X					    ( last->nfollows + 1 ) );
X	
X	last->counts = ( int *) malloc( sizeof( int ) *
X					( last->nfollows + 1 ) );
X
X    }
X    *( last->follows + last->nfollows ) = wd;
X    *( last->counts + last->nfollows ) = 1;
X    last->nfollows++;
X
X}
X
Xvoid erisify( Words *w, long paragraphs, long start )
X
X{
X
X    Words *lastword = chase( w, &start );
X    int count = 0;
X    int paralen = ( random() % 5 ) + 1;
X    int capitalize = 1;
X
X    fsort( lastword );
X
X    printf( ".PP\n" );
X    do {
X
X	Words *theword;
X
X	if ( lastword->nfollows && ( lastword->class != FullStop ) )
X	    theword = findNewWord( lastword );
X	else
X	    do {
X
X		long where = random() % wordcount;
X
X		fsort( theword = chase( w, &where ) );
X
X	    } while ( theword->class != Word );
X	
X	if ( capitalize )
X	    printf( "%c%s", toupper( *( lastword->word ) ), 
X		                      ( lastword->word + 1 ) );
X	else
X	    printf( "%s", lastword->word );
X
X	if ( random() % 200 == 0 )
X	    printf( " fnord" );
X	if ( ( theword->class != Punct ) &&
X	     ( theword->class != FullStop ) &&
X	     ( lastword->class != FullStop ) )
X	    printf( " " );
X	if ( !( ++count % 5 ) && 
X	      ( theword->class != Punct ) &&
X	      ( theword->class != FullStop ) &&
X	      ( lastword->class != FullStop ) )
X	    printf( "\n" );
X
X	if ( lastword->class == FullStop ) {
X
X	    printf( "\n" );
X	    if ( !( --paralen ) ) {
X
X		printf( ".PP\n" );
X		count = 0;
X		paralen = ( random() % 5 ) + 1;
X		--paragraphs;
X
X	    }
X
X	}
X	capitalize = lastword->class == FullStop;
X	fsort( lastword = theword );
X
X    } while ( paragraphs );
X
X}
X
XWords *chase( Words *w, long *count )
X
X{
X
X    Words *wd;
X
X    if ( w->before )
X	wd = chase( w->before, count );
X    if ( *count ) {
X
X	if ( --( *count ) == 0 )
X	    wd = w;
X	else if ( w->after )
X	    wd = chase( w->after, count );
X
X    }
X
X    return wd;
X
X}
X
Xvoid fsort( Words *w )
X
X{
X
X    if ( !w->visited && w->nfollows ) {
X
X	int i;
X	int wsum;
X
X	for ( i = 0; i < w->nfollows - 1; i++ ) {
X
X	    int j;
X
X	    for ( j = i + 1; j < w->nfollows; j++ ) {
X
X		if ( w->counts[i] < w->counts[j] ) {
X
X		    int temp = w->counts[i];
X		    Words *wtemp = w->follows[i];
X
X		    w->counts[i] = w->counts[j];
X		    w->follows[i] = w->follows[j];
X		    
X		    w->counts[j] = temp;
X		    w->follows[j] = wtemp;
X
X		}
X
X	    }
X
X	}
X
X	wsum = w->counts[0];
X	for ( i = 1; i < w->nfollows; i++ ) {
X
X	    wsum += w->counts[i];
X	    w->counts[i] = wsum;
X
X	}
X	w->visited = wsum;
X
X    }
X
X}
X
XWords *findNewWord( Words *w )
X
X{
X
X    if ( w->visited ) {
X
X	int rnum = random() % w->visited;
X	int i;
X
X	for ( i = 0; i < w->nfollows - 1; i++ )
X	    if ( w->counts[i] > rnum )
X		break;
X	
X	return w->follows[i];
X
X    }
X
X}
SHAR_EOF
chmod 0644 discord.c || echo "restore of discord.c fails"
exit 0

exit 0 # in case we lose our brakes and skid...
		      - - - - that's it - - - -
-- 
Steve Lamont, SciViGuy -- (619) 534-7968 -- spl@szechuan.ucsd.edu
UCSD Microscopy and Imaging Resource/UCSD Med School/La Jolla, CA 92093-0608
                 "Tenants of the house,
Thoughts of a dry brain in a dry season." - TS Eliot, "Gerontion"
Newsgroups: alt.slack