Een rebus is een puzzel die één of meer woorden beschrijft aan de hand van een reeks emoji. Bij elke emoji horen ook nul of meer acties die aangeven welke letters toegevoegd, verwijderd of vervangen moeten worden door andere letters. De rebus groepeert emoji (en bijhorende acties) die samen één woord van de oplossing vormen. Zo beschrijft onderstaande rebus twee woorden: het eerste woord wordt beschreven door de eerste drie emoji en het tweede woord door de laatste twee emoji.

rebus (opgave)
De opgave van een rebus.

In tekstformaat beschrijven we een rebus aan de hand van een reeks patronen. Zo wordt bovenstaande voorbeeldrebus beschreven door deze patronen, waarbij we elk patroon ingesloten hebben tussen een paar dubbele aanhalingstekens:

"🐸 f=p" "🚊 -t" "💍 r=m" " " "✋ h=l -d" "🍇 r=u p=g"

Elk patroon beschrijft een deel van de oplossing. Die oplossing bekom je door alle delen te vinden en samen te voegen. Er zijn twee verschillende soorten patronen:

Het bepalen van de letters die beschreven worden door een emoji en de bijhorende acties gebeurt in twee stappen. Eerst moet in een lexicon het woord opgezocht worden dat hoort bij de emoji. Een lexicon is een tekstbestand waarvan elke regel bestaat uit een emoji, een spatie en het woord dat bij die emoji hoort. Elke emoji komt hoogstens één keer in een lexicon voor. Dit is bijvoorbeeld een deel van een lexicon waarin alle emoji uit de voorbeeldrebus voorkomen:

…
🐸 frog
🚊 tram
💍 ring
✋ hand
🍇 grapes
…

Opmerking

Deze opgave gebruikt de UTF-81 (8-bit Unicode Transformation Format) tekencodering om Unicode-tekens voor te stellen als een stroom van bytes. Daarbij is het belangrijk om weten dat een emoji uit meerdere bytes kan bestaan. Je mag er dus niet van uitgaan dat elke emoji bestaat uit één enkel karakter.

Als we het woord gevonden hebben dat bij de emoji hoort, dan moeten we daar vervolgens alle bijhorende acties op toepassen. Het is belangrijk om te onderstrepen dat de acties in de gegeven volgorde (van links naar rechts) moeten toegepast worden. We onderscheiden vier soorten acties:

Onderstaande tabel geeft aan hoe de voorbeeldrebus kan opgelost worden door elk patroon in twee stappen om te zetten naar een deel van de oplossing.

patroon woord (stap 1) acties (stap 2) deel van oplossing
🐸 f=p frog frog prog prog
🚊 -t tram tram ram ram
💍 r=m ring ring ming ming
" "     " "
✋ h=l -d hand hand land lan lan
🍇 r=u p=g grapes grapes guapes guages guages

Als we alle delen samenvoegen dan krijgen we dus de oplossing van de voorbeeldrebus: programming languages.

rebus (oplossing)
De oplossing van de rebus is programming languages.

Opgave

Schrijf een bash shell script rebus waarmee rebussen kunnen opgelost worden. Aan het script moeten twee of meer argumenten doorgegeven worden: i) de padnaam van een lexicon en ii) één of meer patronen die een rebus beschrijven. Het script moet de oplossing van de rebus uitschrijven naar standard output (stdout). Bij het oplossen van de rebus moet het script ervan uitgaan dat er enkel kleine letters gebruikt worden in de woorden van het lexicon, in de acties en dus ook in de oplossing van de rebus.

Het script moet de volgende foutafhandeling voorzien:

In al deze gevallen mag er ook niets uitgeschreven worden naar standard output (stdout).

Voorbeeld

Onderstaande voorbeeldsessie toont hoe het shell script rebus moet kunnen gebruikt worden. Hierbij gaan we ervan uit dat het bestand emoji.txt2 zich in de huidige directory bevindt.

$ rebus
Syntax: rebus [FILE] [PATTERN]...
$ echo $?
1
$ rebus fake.txt "🍕"        # bestand fake.txt bestaat niet
rebus: invalid lexicon
$ echo $?
2
$ rebus emoji.txt3 "🎃 o=x"   # emoji komt niet voor in lexicon
rebus: invalid emoji
$ echo $?
3
$ rebus emoji.txt4 "🍕 -q"    # letter q komt niet voor in woord pizza
rebus: invalid action
$ echo $?
4
$ rebus emoji.txt5 "🍕 z=ti"  # letter z komt twee keer voor in woord pizza
rebus: invalid action
$ echo $?
4
$ rebus emoji.txt6 "🍕 ?"     # onbekende actie
rebus: invalid pattern
$ echo $?
5
$ rebus emoji.txt7 "🐸 f=p" "🚊 -t" "💍 r=m" " " "✋ h=l -d" "🍇 r=u p=g"
programming languages
$ rebus emoji.txt8 🐎 👞
horseshoe