Als Equatoriaal-Guinea halverwege tussen Angola en Mauritius ligt, Noorwegen halverwege tussen El Salvador en Iran, Fiji halverwege tussen Spanje en Gabon, en Ierland halverwege tussen Zuid-Korea en Frans-Guyana, welk land ligt dan halverwege tussen Saudi-Arabië en de Verenigde Staten van Amerika?

haverwege
Welk land ligt halverwege tussen Saudi-Arabië en de Verenigde Staten van Amerika?

Opgave

Als je de "halverwege" op een wereldbol probeert te bepalen, dan zal je snel merken dat bovenstaande verbanden niet kloppen. In plaats daarvan gebruiken we de internationale standaard ISO 3166-11 die voor alle landen een unieke tweeletterige code (alpha-2), een unieke drieletterige code (alpha-3) en een unieke driecijferige code (numeric-3) vastlegt. Deze standaard wordt vastgelegd in het tekstbestand iso_3166-1.txt2:

Country;Alpha-2 code;Alpha-3 code;Numeric code;Latitude (average);Longitude (average)
Afghanistan;AF;AFG;004;33;65
Albania;AL;ALB;008;41;20
Algeria;DZ;DZA;012;28;3
American Samoa;AS;ASM;016;-14.3333;-170
Andorra;AD;AND;020;42.5;1.6
Angola;AO;AGO;024;-12.5;18.5
Anguilla;AI;AIA;660;18.25;-63.1667
Antarctica;AQ;ATA;010;-90;0
Antigua and Barbuda;AG;ATG;028;17.05;-61.8
…

De eerste regel van het bestand is een hoofding. Elke andere regel beschrijft een land aan de hand van zes informatievelden die door puntkomma's (;) van elkaar gescheiden worden: i) unieke naam (Engels), ii) unieke tweeletterige code (alpha-2), iii) unieke drieletterige code (alpha-3), iv) unieke driecijferige code (numeric-3), v) (gemiddelde) breedtegraad en vi) (gemiddelde) lengtegraad. De informatievelden bevatten zelf geen puntkomma's.

Voor elk land gebruiken we de drieletterige code die bestaat uit drie hoofdletters. Om het middelpunt van twee codes te bepalen, leggen we eerst vast hoe we het middelpunt van twee letters bepalen. Daarvoor gebruiken we twee varianten. Het symmetrisch middelpunt van twee letters heeft een positie in het alfabet die precies in het midden ligt tussen de posities van de twee letters, ongeacht de volgorde van die twee posities. Zo is de letter J het symmetrisch middelpunt van de letters F en N die acht posities uit elkaar liggen, en het is ook het symmetrisch middelpunt van de letters N en F.

symmetrisch middelpunt
Het symmetrisch middelpunt van twee letters heeft een positie in het alfabet die precies in het midden ligt tussen de posities van de twee letters, ongeacht de volgorde van die twee posities.

We kunnen de letters van het alfabet ook in wijzerzin rond een cirkel plaatsen, waarbij na de letter Z terug de letter A volgt. Nu moeten we opnieuw 8 stappen zetten om in wijzerzin van de letter F naar de letter N te gaan, waardoor de letter J het asymmetrisch middelpunt is van F en N, omdat die in wijzerzin $$\frac{8}{2} = 4$$ stappen verder ligt dan de letter F. Maar we hebben 18 stappen nodig om in wijzerzin van de letter N naar de letter F te gaan, waardoor de letter W het asymmetrisch middelpunt is van N en F, omdat die in wijzerzin $$\frac{18}{2} = 9$$ stappen verder ligt dan de letter N.

asymmetrisch middelpunt (circulair)
Het asymmetrisch middelpunt van twee letters heeft een positie in een circulair alfabet die in wijzerzin precies in het midden ligt tussen de positie van de eerste letter en de positie van de tweede letter.

Een andere manier om het asymmetrisch middelpunt te bepalen is door het alfabet twee keer na elkaar te zetten. Daarin bepalen we de positie waar de eerste letter voor het eerst voorkomt, en daarna de positie waar de tweede voor het eerst voorkomt vanaf de positie van de eerste letter.

asymmetrisch middelpunt (lineair)
Een andere manier om het asymmetrisch middelpunt te bepalen is door het alfabet twee keer na elkaar te zetten. Daarin bepalen we de positie waar de eerste letter voor het eerst voorkomt, en daarna de positie waar de tweede voor het eerst voorkomt vanaf de positie van de eerste letter.

Het middelpunt van twee drieletterige codes is dan een string (str) van drie hoofdletters, waarvan de eerste letter het middelpunt is van de eerste letters van beide codes, de tweede letter het middelpunt van de tweede letters van beide codes en de derde letter het middelpunt van de derde letters van beide codes. Gevraagd wordt:

Voorbeeld

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

>>> land2codes = lees_standaard('iso_3166_1.txt5')
>>> land2codes['Angola']
('AO', 'AGO', '024')
>>> land2codes['Mauritius']
('MU', 'MUS', '480')
>>> land2codes['Equatorial Guinea']
('GQ', 'GNQ', '226')

>>> code2land = omkeren(land2codes)
>>> code2land['AGO']
'Angola'
>>> code2land['MUS']
'Mauritius'
>>> code2land['GNQ']
'Equatorial Guinea'

>>> middelletter('F', 'N')
'J'
>>> middelletter('N', 'F')
'J'
>>> middelletter('F', 'N', asymmetrisch=True)
'J'
>>> middelletter('N', 'F', asymmetrisch=True)
'W'
>>> middelletter('A', 'D')
Traceback (most recent call last):
AssertionError: geen middelpunt

>>> middelcode('AGO', 'MUS')
'GNQ'
>>> middelcode('ISL', 'CYP')
'FVN'
>>> middelcode('ISL', 'CYP', asymmetrisch=True)
'SVN'
>>> middelcode('KHM', 'VNM')
Traceback (most recent call last):
AssertionError: geen middelpunt

>>> halverwege('Angola', 'Mauritius', land2codes)
'Equatorial Guinea'
>>> halverwege('Iceland', "Cyprus", land2codes)
Traceback (most recent call last):
AssertionError: geen middelpunt
>>> halverwege('Iceland', "Cyprus", land2codes, asymmetrisch=True)
'Slovenia'