Semafoorseinen is een manier van communiceren die vroeger vooral in de scheepvaart gebruikt werd. Daarbij houdt een seingever in elke hand een vlaggetje vast dat in acht mogelijke posities kan gehouden worden. De posities worden genummerd vanaf nul, te beginnen bij de positie recht naar boven en dan telkens 45° gedraaid in wijzerzin.

semafoorposities
Het semafoorsein 17 (of 71) correspondeert in het internationaal semafooralfabet met de hoofdletter U.
letter U
Een bemanningslid van de Amerikaanse marine seint de letter U met een vlaggensemafoor tijdens een bevoorradingsoefening (2005).

Een semafoorsein (of kortweg semafoor) wordt voorgesteld als een string (str) met twee cijfers tussen 0 en 7 (grenzen inbegrepen) die de posities van beide vlaggetjes aangeven. De volgorde van de cijfers maakt geen verschil, omdat het niet uitmaakt met welke hand de posities aangenomen worden. Zo stellen 17 en 71 bijvoorbeeld dezelfde semafoor voor.

Een semafooralfabet bestaat uit 28 verschillende semaforen: 26 semaforen die de hoofdletters (AZ) voorstellen, en dan nog twee semaforen die een spatie en een hekje (#) voorstellen. Tien semaforen die hoofdletters voorstellen (maar niet de hoofdletter J) stellen daarnaast ook nog de 10 cijfers (09) voor. Er bestaan verschillende semafooralfabetten, maar dit alfabet is internationaal het meest gangbaar.

semafooralfabet
Internationaal semafooralfabet: posities van de vlaggetjes (boven), voorstelling met twee cijfers (linksonder; zwart) en corresponderende symbolen (rechtonder; blauw).

Bij het interpreteren van opeenvolgende semaforen kunnen we ons in lettermodus of in cijfermodus bevinden. Als we beginnen seinen dan bevinden we ons altijd in lettermodus. In lettermodus gebruiken we de hoofdletter voor semaforen die twee symbolen (een hoofdletter en een cijfer) voorstellen. De semafoor die het hekje (#) voorstelt zorgt ervoor dat we in cijfermodus terechtkomen (die semafoor stelt dus verder geen symbool voor). In cijfermodus gebruiken we het cijfer voor semaforen die twee symbolen (een hoofdletter en een cijfer) voorstellen. In cijfermodus zorgt de semafoor die de hoofdletter J voorstelt ervoor dat we terug in lettermodus terechtkomen (die semafoor stelt dus verder geen symbool voor). Voor semaforen die slechts één symbool voorstellen (een hoofdletter of een spatie, maar geen J of #) maakt het geen verschil of we ons in lettermodus of in cijfermodus bevinden.

We stellen de weergave van een tijdstip op een digitale 24-uursklok voor als een string (str) in het formaat uu:mm. Daarbij worden de uren $$u$$ ($$0 \leq u < 24$$) en de minuten $$m$$ ($$0 \leq m < 60$$) altijd met twee cijfers weergegeven door waar nodig voorloopnullen toe te voegen. Bijvoorbeeld 13:50 of 07:03.

analoge klok
Op basis van de weergave van tijdstip 13:50 op een analoge klok, kunnen we de stand van de twee wijzers interpreteren als semafoor 17 (of 71).

Als we een tijdstip weergeven op een analoge klok, dan kunnen we de stand van de uurwijzer en de minuutwijzer interpreteren als een semafoor. De hoeken $$\alpha_u$$ en $$\alpha_m$$ (in graden) die de uur- en minutenwijzers maken, kunnen berekend worden als \[ \begin{align} \alpha_u &= 30\,(u\!\!\!\!\!\mod{12}) + \frac{m}{2} \\ \alpha_m &= 6\,m \end{align} \] Daarna gebruiken we deze formule om de semafoorpositie $$p_\alpha$$ te bepalen die correspondeert met de hoek $$\alpha$$ (in graden) van de wijzer van een analoge klok: \[ p_\alpha = \left[\frac{\alpha}{45}\right]\!\!\!\!\!\mod{8} \] Hierbij stelt $$\left[x\right]$$ de afronding van $$x \in \mathbb{R}$$ naar het dichtsbijzijnde gehele getal voor.

Opgave

We werken met tekstbestanden die een semafooralfabet beschrijven. Zo'n bestand bestaat uit 28 regels, waarvan elke regel bestaat uit één van de twee mogelijke voorstellingen van een semafoor, gevolgd door een tab en één of twee symbolen die door de semafoor voorgesteld worden. Bij semaforen die corresponderen met twee symbolen, staat de hoofdletter altijd voor het cijfer. Dit zijn bijvoorbeeld enkele regels uit het bestand met het internationaal meest gangbare semafooralfabet (alfabet.txt1):

54	A1
64	B2
74	C3
04	D4
14	E5
…
15	L
25	M
35	N
67	O
60	P
…
12	W
13	X
23	Z
44	 
01	#

Merk op dat semafoor 44 in dit alfabet een spatie voorstelt, waardoor er op de voorlaatste regel van het bestand nog een spatie staat na de tab.

Het is jouw opdracht om een reeks tijdstippen zoals

17:55 01:59 22:29 03:03 21:01 12:08 00:38

te interpreteren als een bericht dat met semaforen doorgeseind wordt. Hieronder zie je hoe we de reeks tijdstippen die we als voorbeeld gebruikt hebben, kunnen interpreteren als het bericht C3P02.

C3P0
De bovenste reeks tijdstippen stelt een bericht voor dat we kunnen ontcijferen door eerst elk tijdstip weer te geven op een analoge klok. Daarna kunnen de uur- en minuutwijze van elke analoge klok interpreteren als een semafoor (midden). Tenslotte kunnen we elke semafoor omzetten naar zijn corresponderende symbool, rekening houdend met de overgangen tussen lettermodus (oranje) en cijfermodus (groen). Het bericht leest dus als C3P0.

Merk op dat semafoor 06 volgens dit semafooralfabet enkel de hoofdletter P voorstelt (en geen cijfer), waardoor het niet strikt nodig was om tussen het doorseinen van de cijfers 3 en 0 (in cijfermodus) terug te keren naar lettermodus. We hadden C3P0 dus ook kunnen voorstellen met deze reeks tijdstippen

17:55 01:59 22:29 21:01 00:38

Gevraagd wordt:

Voorbeeld

In onderstaande voorbeeldsessie gaan we ervan uit dat het tekstbestand alfabet.txt3 zich in de huidige directory bevindt.

>>> alfabet = semafooralfabet('alfabet.txt4')
>>> alfabet['24']
'F6'
>>> alfabet['42']
'F6'
>>> alfabet['26']
'R'
>>> alfabet['44']
' '
>>> alfabet['10']
'#'
>>> alfabet['37']
Traceback (most recent call last):
KeyError: '37'

>>> tijdstip2semafoor('12:43')
'06'
>>> tijdstip2semafoor('05:17')
'42'
>>> tijdstip2semafoor('04:45')
'36'

>>> semafoor2tijdstippen('06')
{'00:42', '00:43', '00:44', '00:45', '08:57', '08:58', '08:59', '09:00', '09:01', '09:02', '09:03', '11:42', '11:43', '11:44', '11:45', '11:46', '11:47', '11:48', '12:42', '12:43', '12:44', '12:45', '20:57', '20:58', '20:59', '21:00', '21:01', '21:02', '21:03', '23:42', '23:43', '23:44', '23:45', '23:46', '23:47', '23:48'}
>>> semafoor2tijdstippen('42')
{'02:27', '02:28', '02:29', '02:30', '02:31', '02:32', '02:33', '03:27', '03:28', '03:29', '03:30', '03:31', '03:32', '03:33', '05:15', '05:16', '05:17', '05:18', '06:12', '06:13', '06:14', '06:15', '06:16', '06:17', '06:18', '14:27', '14:28', '14:29', '14:30', '14:31', '14:32', '14:33', '15:27', '15:28', '15:29', '15:30', '15:31', '15:32', '15:33', '17:15', '17:16', '17:17', '17:18', '18:12', '18:13', '18:14', '18:15', '18:16', '18:17', '18:18'}
>>> semafoor2tijdstippen('36')
{'03:46', '03:47', '03:48', '04:42', '04:43', '04:44', '04:45', '04:46', '04:47', '04:48', '08:19', '08:20', '08:21', '08:22', '08:23', '08:24', '08:25', '08:26', '09:19', '09:20', '09:21', '09:22', '09:23', '09:24', '09:25', '09:26', '15:46', '15:47', '15:48', '16:42', '16:43', '16:44', '16:45', '16:46', '16:47', '16:48', '20:19', '20:20', '20:21', '20:22', '20:23', '20:24', '20:25', '20:26', '21:19', '21:20', '21:21', '21:22', '21:23', '21:24', '21:25', '21:26'}

>>> tijdstip2symbool('22:30', alfabet)
'C'
>>> tijdstip2symbool('12:07', alfabet)
'#'
>>> tijdstip2symbool('10:30', alfabet, cijfermodus=True)
'3'
>>> tijdstip2symbool('12:15', alfabet, cijfermodus=True)
'J'
>>> tijdstip2symbool('09:03', alfabet)
'P'
>>> tijdstip2symbool('12:08', alfabet)
'#'
>>> tijdstip2symbool('12:37', alfabet, cijfermodus=True)
'0'
>>> tijdstip2symbool('15:13', alfabet)
Traceback (most recent call last):
AssertionError: ongeldig tijdstip

>>> kloklezen('17:55 01:59 22:29 03:03 21:01 12:08 00:38', alfabet)
'C3P0'
>>> kloklezen('17:55 01:59 22:29 21:01 00:38', alfabet)
'C3P0'
>>> kloklezen('10:02 22:37 14:41 13:30 18:28 19:56 16:46 17:32 19:16 22:47 19:25 06:06 23:12', alfabet)
'TIME IS MONEY'
>>> kloklezen('11:51 19:54 07:17 18:06 05:28 06:49 16:49 18:27 18:43 11:04 04:39 11:36', alfabet)
Traceback (most recent call last):
AssertionError: ongeldig tijdstip

Epiloog

Het internationaal symbool voor de vrede (☮) werd in 1958 ontworpen door de Britse ontwerper en kunstenaar Gerald Holtom5. Het is een cirkel met een verticale streep in het midden van waaruit twee schuine strepen naar beide zijden lopen. Het symbool is gebaseerd op het semafooralfabet: de twee schuine strepen naar beide zijden staat voor de letter N van nuclear (nucleair) en de verticale streep staat voor de letter D van disarmament (ontwapening).

vredessymbool
Het internationaal symbool voor de vrede (☮) werd in 1958 ontworpen door de Britse ontwerper en kunstenaar Gerald Holtom. Het is een cirkel met een verticale streep in het midden van waaruit twee schuine strepen naar beide zijden lopen. Het symbool is gebaseerd op het semafooralfabet: de twee schuine strepen naar beide zijden staat voor de letter N van nuclear (nucleair) en de verticale streep staat voor de letter D van disarmament (ontwapening).