[net.games.frp] Pseudo-Sindarin Name Generator

urban (03/31/83)

This is a somewhat long (300-line) message.  It comprises three
segments, the first of which is the explanation you're
reading.  The second  is a C program which accumulates
statistics on alphabetic triplets from standard input and
produces words on standard output with the same statistical
properties. The third segment is an abbreviated Sindarin
(as in Tolkien Grey-Elven) word-list (it has not yet
assimilated most of the new material from Unfinished Tales
and the Letters). Make this file the standard input for
the supplied program.  If you call the program "trigraph", then

	trigraph 20 < sindarin

will produce a list of 20 Sindarin-like (and occasionally
genuine Sindarin) words on standard output.  If no numeric
count is given, 'trigraph' will produce tables suitable for
use with percentage dice.  The purpose of this material
(which is why it's posted to this newsgroup) is to allow
you to generate reasonably euphonious names for people,
places, weapons, trees, etc, etc in your gaming, without
having to use "real" Elvish words with their
Tolkien-oriented meanings and mythic associations.  A quick
sample of the output (sorted and encolumned)

adaeg        cuand        duil         lhadron      naegilivrist
andorin      dagalroth    gladrial     maerdhrin    nelithrim
annunen      dalad        imlast       merethil     paurannu
arved        dorthiw      ladagnon     moros        thrielad

Let's see... none of these words actually occurs in the
input data.  Some of them (annunen, 'west-water') can be
intelligibly glossed by the Sindarin expert (nelithrim:
'three-ash-people' ?).  Anyway, there's little work
involved, and maybe this stuff can help stimulate your
FRPing imagination a little.
================================================================
#
#include <stdio.h>
#include <ctype.h>

int     freq[27][27][27];	/* Counts occurrences of triplets */
				/* I assume it's initially zero.  If */
				/* you don't, add an initialization loop*/
long    time ();
	
int	shortest=4;		/* Default word sizes */
int	longest=12;

main (argc, argv) char **argv;
{
    char    c,
            oldc,
            olderc;
    int     count;

/*	Usage: trigraph [count [shortest [longest]] */
/*	   with no options, outputs its table in    */
/*	   percentage-dice form			    */

    if (argc > 1) {
	count = atoi (argv[1]);
    }
    else
	count = 0;
    if (argc > 2)
        shortest = atoi (argv[2]);
    if (argc > 3)
	longest = atoi (argv[3]);

    olderc = oldc = 'z' - 'a' + 1;	/* 26, in the Common Speech */

    while ((c = getchar ()) != (char)EOF) {
	if (isupper(c))
	    c = tolower(c);
	if (!isalpha(c))
	    c = 'z' + 1;	/* Separator char */
	freq[olderc][oldc][c - 'a']++;
	olderc = oldc;
	oldc = c - 'a';
	if (!isalpha (c))	/* Word break, re-initializes */
	    olderc = oldc;
    };
    freq[olderc][oldc][27 - 1]++;
    freq[27 - 1][27 - 1][27 - 1] = 0;
    out_freq (count);
}


out_freq (count) int    count; {

    int     row[27][27];
    int     i,
            j,
            k;

    char    outbuf[80],
           *obuf;
    int     lastc,
            nextc,
            newc,
            cum,
            pct;
    char    done;


    for (i = 0; i < 27; i++) {
	for (j = 0; j < 27; j++) {
	    row[i][j] = 0;
	    for (k = 0; k < 27; k++) {
		row[i][j] += freq[i][j][k];
	    }
	}
    }
    for (i = 0; i < 27; i++) {
	for (j = 0; j < 27; j++) {

	    if (row[i][j]) {
		cum = 0;
		/* Normalize frequencies to chance-in-1000 */
		for (k = 0; k < 27; k++) {
		    freq[i][j][k] = (freq[i][j][k] * 1000 + row[i][j] / 2)
			/ row[i][j];
		    cum += freq[i][j][k];
		    if (!count)
			outpct (i, j, k, cum);
		}
		if (!count)
		    printf ("--------\n");
	    }
	}
    }
    if (!count)
	exit (0);


    i = (int) time ((long *) 0);

    srand (i);
    while (1) {
	obuf = outbuf;
	nextc = lastc = 26;
	do {
	    cum = 0;
	    done = 0;
	    while (!done) {	/* Maybe have to roll again */
		pct = 1 + randint (1000);
		for (i = 0; i < 27; i++) {
		    cum += freq[lastc][nextc][i];
		    if (cum >= pct) {
			newc = i;
			done = 1;
			break;
		    }
		}
	    }
	    if (newc < 27 - 1)
		*obuf++ = 'a' + newc;
	    else
		nextc = newc;
	    if ((obuf-outbuf) > longest)
	    	newc = 26;
	    lastc = nextc;
	    nextc = newc;
	} while (nextc != 26);
	*obuf++ = '\0';
	if (strlen (outbuf) >= shortest && strlen (outbuf) <= longest) {
	    printf ("%s\n", outbuf);
	    if (--count <= 0)
		exit (0);
	}
    }
}

outpct (i, j, k, cum) int   i,
                            j,
                            k,
                            cum;
{
    if (freq[i][j][k]) {
	printf ("%c", (i == 26 ? '-' : 'a' + i));
	printf ("%c", (j == 26 ? '-' : 'a' + j));
	printf ("%c", (k == 26 ? '-' : 'a' + k));
	printf (" %4d\n", cum);
    }
}

#ifndef RANDINT
int     randint (max)	/* produce a random int in the range 0 to max-1 */
int    max;
{
    return (hmul (2 * max, rand ()));
}

#ifdef vax

int     hmul (a, b)		/* high-order word of a*b (David
				   Smallberg, UCLA) */
int     a,
        b;
{
    asm ("	emul	4(ap),8(ap),$0,r0");
				/* r1'r0 <= a*b		 */
    asm ("	movl	r1,r0");/* r0 <=  (a*b).high	 */
}

#else

typedef
union {
    unsigned long   ufull;
    struct {
	unsigned short  ulo;
	unsigned short  uhi;
    }       uhalves;		/* Requires PDP-11-style addressing */
} upair;

int     hmul (a, b)
register    upair a,
            b;
{
    register    upair cross1,
                cross2,
                total;

    cross1.ufull = a.ulo * b.uhi;
    cross2.ufull = a.uhi * b.ulo;
    total.ufull = a.ulo * b.ulo;
    total.ufull = total.uhi + cross1.ulo + cross2.ulo;
    return (total.uhi + cross1.uhi + cross2.uhi + a.uhi * b.uhi);
}

#endif vax
#endif RANDINT
================================================================
-chaered -chebin -dIriel -danwedh -dhol -dil -diriel -dolen -elleth
-gaurhoth -guinar -im- -ndaedelos -ndengin -nor- -nu- -nuin- -rass
-remmin -rist -thoniel El Onen U- U-chebin Umarth a adan adanedhel adar
aduial adurant aear aearon aeglos aegnor aelin aelin-uial aerandir
aerlinn aew agarwaen aglar aglareb aglarond aglon aiglos alph amarth
amon amrUn anOrien anann and andaith andram andros anduin anfalas
anfanglir anfauglith ang angband angerthas anghabar anglachel angren
angrenost angrist anim annUminas annUn annon annon-in-gelydh anor ar-
ar-feiniel aran aranrUth araw ard- ard-galen ardhon aredhel argonath
arnoediad arnor arossiach arvedui arwen ascar athelas athrad aur balrog
bar bar-en-danwedh barad barad-dur baran baranduin bauglir beleg
belegUr belegaer belegost belegurth beleriand belthil belthronding
beraid bereth berhael beth bragol bragollach bregalad brethil brilthor
brith bruinen cIrdan cU cUarthol cUthalion cabed cair calan calen
calenardhon cam camlost carach caradhras caran caran-rass caras carch
carcharoth carchost carnen cebir celduin celeb celebdil celeborn
celebrant celebrimbor celebrin celebrindal celebros celerdain cerin
cirith cirth cormallen crissthorn cuio curunIr dIn dInen dOr dU dUath
dUlin dUn dUnadan dUnedain dUr dae daedeloth dagnir dagor
dagor-nuin-giliath dagorlad dal daro daur del deldUwath deloth di-
di-nguruthos dim- dimrost dirnen dol dolmed dor dor-nu-fauglith doriath
dorthonion drUadan drUwaith draug duhirion duin duinath dungortheb e-
e-ndaedelos echant echor echoriath echui ecthelion edain edhel edhil
edro egladil eglath eglerio eithel elanor elbereth eledhwen elenath
elrond elros eluchIl elurEd elurIn elwing emeldir emyn en en- enedwaith
engrin ennor ennorath ennyn enyd ephel erain erchamion ereb erebor ered
ereg eregion ereinion ernil eryd eryn esgal esgalduin estel estolad
ethir ethuil fAn faelivrin falas falathrim fan- fangorn fanui fanuidhol
fanuilos faroth faug- fauglith feanor feiniel fen fennas fimbrethil
fing finglas firith firn- firn-i-guinar fladrif for- forn fornost forod
fuin g- gUl gaer galad galadh galadhon galadhremmin galadhrim galadon
galadriel galadrim galen galenas galvorn gaur gebir gelin gil gil-estel
gil-galad giliath gilthoniel girith glIn glamdring glamhoth glanduin
glingal glorfindel gloss golodh gond gond-dolen gondolin gondolindrim
gondor gonnhirrim gor gorgor gorgoroth gorlim goroth gorthad gorthaur
gorthol govannen grod grond groth guldur gurth gurthang gwaihir gwaith
gwaith-i-mIrdain gwath gwathlO hIn hIr hIril hIrilorn hIth hadhod
hadhodrond haerast hain har- harad haradrim haradwaith harn harondor
haudh heledh helevorn hen henneth him himlad himring hin hithaeglir
hithlain hithlum hollen hoth huan i i-estel i-pheriannath iA iAth iant
iarwain iaur iavas im imlad imlad-rist imladris in ithil ithildin lOm
lOmin lOrindol lYg labadal lad laer lalaith lamath lammen lamoth
lanthir lasgalen lass lasto le legolas leithian lembas lhUg lhach lhaw
lin linaewen lindon linnathon lith lithlad lithui loeg lond loss
loss-hoth lossen lossoth loth lothlOrien lothlann luin mIr mIrdain
mIriel mablung mae maeg maeglin malduin melian mellon menegroth menel
menelvagor mereth merethrond methedras minas mindolluin minhiriath
minno minuial mith mitheithel mithlond mithrandir mithril mithrim
mithrin mor morannon morchaint mordor morgoth morgul moria mormegil
morthond morwen moth nIn nIniel na na-chaered naeramarth naith nallon
nan nan-tathren nand nanduhirion narbeleth nargothrond narn naug
nauglamIr naugrim naur nef neithan neldor nen nenuial nevrast nguruthos
nibin nienor nim nimf nimloth nimp nimrais nimras nimrodel nin nindalf
ningloron ninniach niphred nirnaeth nivrim noegyth nogoth nogothrim
nogrod novrod o odo onodrim or- oraeron orch orcrist orn orod orodruin
orthanc os osgiliath ossir ossiriand ost ost-in-edhil ostgiliath palan-
palan-diriel palandIriel parth paur pedo pelargir pelennor penna
peredhel peredhil periain perian periannath pheriain pheriannath
pinnath rUdh rUth rais ram ramdal rammas rant ras rathlOriel raug
rauros rem remmirath rhIw rhUn rhUnen rhovanion rim ring roch rochand
rog rohan roheryn rohirrim rond ros ruin sI sIr sUl sammath sarn
sarn-athrad sereg seregon silivren sirannon sirion sirith tIw tal talan
talath talf tathar tathren taur taur-im-duinath taur-nu-fuin tauron
teithant thOl thOn thalion thang thangorodrim tharbad thargelion thaur
thil- thind thingol thiw thond thoron thoronath thorondor thuringwethil
til tinUviel tirith tiro tol tol-in-gaurhoth torech torog tum tumladen
turamarth tyrn udUn uial uilos ungol unlol vedui wath wethrin yrch
ithron ithryn