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