In 1951 werd James Thurber1 door zijn vriend Joseph Mitchell2 uitgedaagd om een Engels woord te vinden dat de vier opeenvolgende letters SGRA bevat. Die nacht in bed bedacht Thurber de volgende woorden:

Helaas staat geen enkel van deze woorden in het woordenboek. Aan welk woord dacht Mitchell dan wel?

Disgrace (schande).

Dit mag dan misschien wel het meest gangbare woord zijn waarin de opeenvolgende letters SGRA voorkomen, in de meeste Engelse woordenboeken is het zeker niet het enige. Denk bijvoorbeeld maar aan palsgrave3 (paltsgraaf; ambt dat in de loop der eeuwen ook een vorstelijke titel werd), grosgrain4 (soort stof die gekenmerkt wordt door een geribbeld uiterlijk), dysgraphia5 (schrijfstoornis) of sgraffito6 (kunstvorm waarbij in verse mortel een lijntekening gekrast en ingekleurd wordt volgens de fresco-techniek). Dit zijn echter allemaal woorden van vreemde origine.

In het Nederlands komen de opeenvolgende letters SGRA trouwens veel vaker voor dan in het Engels. Denk bijvoorbeeld maar aan asgrauw, gasgranaat, jongensgrap, koningsgraf, moeilijkheidsgraad, olifantsgras, stadsgracht of visgraat.

Opgave

Een $$n$$-gram is een string (str) met $$n$$ letters. In een $$n$$-gram mogen enkel de 26 letters van het alfabet (az) voorkomen, dus geen spaties, leestekens of letters met diakritische tekens7. Gevraagd wordt:

De functies aantal_ngrammen en uniek_ngram mogen de gegeven dictionary nooit wijzigen. De tekstbestanden die aan de functie woordenboek doorgegeven worden, gebruiken de UTF-88 tekencodering. Bij het openen van een tekstbestand kan je de gebruikte tekencodering meegeven aan de parameter encoding van de ingebouwde functie open:

>>> open('bestand.txt', 'r', encoding='utf-8')

Epiloog

Uit een essay dat A.A. Milne9 in 1921 schreef:

TERALBAY is not a word which one uses much in ordinary life. Rearrange the letters, however, and it becomes such a word. A friend — no, I can call him a friend no longer — a person gave me this collection of letters as I was going to bed and challenged me to make a proper word of it. He added that Lord Melbourne — this, he alleged, is a well-known historical fact — Lord Melbourne had given this word to Queen Victoria once, and it had kept her awake the whole night. After this, one could not be so disloyal as to solve it at once. For two hours or so, therefore, I merely toyed with it. Whenever I seemed to be getting warm I hurriedly thought of something else. This quixotic loyalty has been the undoing of me; my chances of a solution have slipped by, and I am beginning to fear that they will never return. While this is the case, the only word I can write about is TERALBAY.

Het antwoord is niet RATEABLY of BAT-EARLY, dat wel "iets zou moeten betekenen, maar het niet doet". Rudolf Flesch10 merkt op dat TRAYABLE geen Engels woord is en dat, hoewel TEARABLY in klein lettertype opgenomen werd in het Webster's Unabridged woordenboek, "het duidelijk geen betekenis zou mogen hebben".

Wat is het antwoord dan wel? Er is geen truc — het is een gangbaar Engels woord.

BETRAYAL

Voorbeeld

In onderstaande voorbeeldsessie gaan we ervan uit dat de tekstbestanden woordenboek.en.txt11 en woordenboek.nl.txt12 zich in de huidige directory bevinden.

>>> ngrammen('Disgrace', 4)
['Disg', 'isgr', 'sgra', 'grac', 'race']
>>> ngrammen('vergeet-mij-nietje', 3)
['ver', 'erg', 'rge', 'gee', 'eet', 'mij', 'nie', 'iet', 'etj', 'tje']
>>> ngrammen('façade', 2)
['fa', 'ad', 'de']
>>> ngrammen('A4-formaat', 2)
['fo', 'or', 'rm', 'ma', 'aa', 'at']

>>> engels = woordenboek('woordenboek.en.txt13', 4)
>>> engels['SGRA']
{'disgrading', 'disgrade', 'disgracers', 'misgrafts', 'palsgrave', 'hansgrave', 'disgracement', 'misgraded', 'misgrading', 'disgracer', 'disgraced', 'grosgrain', 'misgracious', 'disgracive', 'disgrace', 'predisgrace', 'palsgraf', 'disgracing', 'dysgraphia', 'misgrafting', 'disgraded', 'disgracefulness', 'misgraft', 'misgrave', 'misgraffed', 'misgrade', 'grosgrained', 'disgraceful', 'disgracia', 'disgracefully', 'disgracious', 'grosgrains', 'disgradation', 'disgraces', 'sgraffiti', 'crossgrainedness', 'misgraff', 'sgraffiato', 'undisgraced', 'disgradulate', 'misgrafted', 'sgraffito', 'palsgravine'}
>>> aantal_ngrammen(engels)
63546
>>> aantal_ngrammen(engels, 1)
13711
>>> aantal_ngrammen(engels, 2)
7408
>>> aantal_ngrammen(engels, 3)
4613
>>> uniek_ngram(engels)
('RLBU', 'pearlbush')
>>> uniek_ngram(engels)
('FIFR', 'kefifrel')
>>> uniek_ngram(engels)
('PPAT', 'wappato')

>>> engels = woordenboek('woordenboek.en.txt14', 3)
>>> engels['GNT']
{'sovereignties', 'pgntt', 'supersovereignty', 'pgnttrp', 'sovereignty', 'cosovereignty', 'semisovereignty'}
>>> aantal_ngrammen(engels)
9025
>>> aantal_ngrammen(engels, 1)
1125
>>> aantal_ngrammen(engels, 2)
561
>>> aantal_ngrammen(engels, 3)
332
>>> uniek_ngram(engels)
('HMP', 'rhythmproof')
>>> uniek_ngram(engels)
('IPZ', 'leipzig')
>>> uniek_ngram(engels)
('LZH', 'alzheimer')

>>> nederlands = woordenboek('woordenboek.nl.txt15', 4)
>>> nederlands['SGRA']
{'visgraatje', 'bezettingsgraad', 'hardheidsgraad', 'asgrauwe', 'jongensgrappen', 'verzuringsgraad', 'doctorsgraden', 'alfabetiseringsgraad', 'werkgelegenheidsgraad', 'schansgravers', 'orpheusgrasmussen', 'visgraatmotief', 'moeilijkheidsgraad', 'werkloosheidsgraad', 'stadsgrachten', 'zeemansgraf', 'tewerkstellingsgraad', 'basisgrammatica', 'varkensgras', 'werkloosheidsgraden', 'werkingsgraad', 'leesgrage', 'scholingsgraad', 'ontwikkelingsgraad', 'vullingsgraad', 'glansgraad', 'Bosgra', 'koersgrafieken', 'vervuilingsgraad', 'activiteitsgraad', 'traangasgranaten', 'visgraatpatronen', 'gifgasgranaten', 'paltsgraven', 'visgraatdessins', 'kostendekkingsgraden', 'bewustzijnsgraad', 'visgraat', 'beladingsgraad', 'oorlogsgraf', 'zelfvoorzieningsgraad', 'oorlogsgraven', 'hellingsgraad', 'paltsgraaf', 'liesgras', 'koningsgraf', 'dekkingsgraden', 'moeilijkheidsgraden', 'visgraatdiagram', 'gasgranaten', 'vrijheidsgraad', 'beschavingsgraad', 'vrijheidsgraden', 'gasgranaat', 'doctorsgraad', 'asgrauw', 'besmettingsgraad', 'dekkingsgraad', 'luchtvochtigheidsgraad', 'beursgraadmeters', 'automatiseringsgraad', 'bezettingsgraden', 'leesgraag', 'Palsgraaf', 'koersgrafiek', 'stadsgracht', 'bedekkingsgraad', 'opleidingsgraad', 'olifantsgras', 'vochtigheidsgraad', 'beschermingsgraad', 'molenaarsgraaf', 'benuttingsgraad', 'zeemansgraven', 'hardheidsgraden', 'paltsgravin', 'bewolkingsgraad', 'struisgras', 'beursgraadmeter', 'koningsgraven', 'kostendekkingsgraad', 'visgraten', 'uitbuitingsgraad', 'paltsgraafschap', 'visgraatjes', 'jongensgrap', 'traangasgranaat', 'werkzaamheidsgraad', 'zuiverheidsgraad'}
>>> aantal_ngrammen(nederlands)
57210
>>> aantal_ngrammen(nederlands, 1)
8224
>>> aantal_ngrammen(nederlands, 2)
7360
>>> aantal_ngrammen(nederlands, 3)
3856
>>> uniek_ngram(nederlands)
('LAMR', 'glamrock')
>>> uniek_ngram(nederlands)
('ACGL', 'cognacglazen')
>>> uniek_ngram(nederlands)
('ALOL', 'afvalolie')