This question got me nostalgic: Build a word generator!
In the '80s I wrote a simple word generator in under 42kB (code and working memory) that would take a collection of strings and use them to create new words and phrases.
Your task is to recreate this program in as few bytes as possible, with a few minor updates.
Your program will take the input and ensure that there are two spaces after each sentence. Each sentence should end with a full-stop (.
). There must not be three consecutive spaces anywhere in the text. Line breaks should be replaced by a single space. There should only be two spaces after a sentence and nowhere else.
Record the number of times each character triplet appears. If you're using regex to break up the text /\X/
is a good way to match a Unicode glyph (could be multiple codepoints, not necessarily a single codepoint). For the purposes of counting, assume that there are two spaces at the start of the text and two spaces at the end.
Hopefully, you now have some good data to work with! Randomly select a triplet where the first two characters are both spaces. For example, if the only two matching triplets are [' ', ' ', 'I'] => 3
and [' ', ' ', 'A'] => 7
there should be a 30% chance of selecting I
and a 70% chance of selecting A
. Shift the characters along and randomly select one of the next triplets. If A
was the first character selected the next triplets might be [' ', 'A', 'n'] => 2
, [' ', 'A', 't'] => 2
and [' ', 'A', 's'] => 3
. Randomly select one using the correct weightings and so on. Repeat until the last two characters are both spaces, then output the string generated if it's 100 characters or longer. If the output is less than 100 characters, repeat the process again, adding to the existing string until it is at least 100 characters long.
You should end up with output something like below, which looks almost like the input language. As my test input I used the first chapter of Charles Dickens' A Tale of Two Cities but you can use any text you feel like. Please provide a link to your input text (preferably not copyrighted) and a sample of the output.
In harithe dir, in hadede Fards fouses, by we aws, mand by nouse St. Merty exce, he th at ing ithe inceir farce, a Capir bod day, one defor ond rodmane of the ce witsethe after seas a pleark parison a prion to eves hund Parglairty the beere tielaires, and wrece to ente comses itic plaw andozene hich tat andiver, a he pent wer thneople, the werseved froads se sebron theire mands inge Woodmage larestown ther Ligh, sed and was the withaved broce pers. Brity-fired of bust a din humakings th, incre pas of the amonoblis the a kne Chrooteres, to offle ound lies yeargland this thing by on the goil ituarivesdozen, moolurd instive the whe only a king was thelfe one divery. Und the intren a king thiging ors, and he tow, afty out pas musears, thot he in aces, it it Fran, tho the blets be anglaters ouseticiodmand whimeng was by the primed tord a ce a dirience.
TL;DR
Build sentences from test input by analysing the frequency of the character triplets, and using those frequencies to randomly select each character in sequence.
You can pre-format your text to make sure it matches the input requirements. It doesn't have to contribute to your byte-count.
If your language can't cope with Unicode at all, limit the input to ASCII characters. Ideally, your program should be able to cope with combining marks (accents and the like) if they are encoded separately but it doesn't have to. It shouldn't affect the output much, although it's possible you might get weird output in rare cases. e.g. if é
is encoded as two codepoints, e
+combining acute accent, it SHOULD (but doesn't HAVE to) treat it as a single glyph.
é
could be one codepoint or two: ane
with a combining acute accent. Ideally your program should keep the accent with the letter, if it happens to be encoded separately. That's what/\X/
does. For example in Sinhala ක is 1 codepoint, and ක් and කො are both 2 but/\X/
will match each of them as a single glyph. You probably won't get weird glyphs if your program treats them separately. \$\endgroup\$