In het Japans zijn er twee manieren om getallen op te schrijven: met de voor ons gebruikelijke Arabische cijfers (1, 2, 3, …) of met de Chinese cijfers (一, 二, 三, …). De Arabische cijfers worden vaker gebruikt in horizontale regels en de Chinese cijfers worden meestal gebruikt in verticale regels.

De omzetting van Arabische naar Chinese cijfers volgt de Chinese traditie waarbij de cijfers vanaf rechts gegroepeerd worden per grootte van 10.000. Zo'n groep van vier cijfers wordt een myriade genoemd. Hieronder wordt bijvoorbeeld de omzetting van het getal 1234567890 naar Chinese cijfers uitgewerkt.

  1234567890
  0012 3456 7890
Arabisch 0 (×1000) 0 (×100) 1 (×10) 2 3 (×1000) 4 (×100) 5 (×10) 6 7 (×1000) 8 (×100) 9 (×10) 0
Chinees     三千 四百 五十 七千 八百 九十  

In eerste instantie wordt het getal 1234567890 opgesplitst in drie myriaden: 0012, 3456 en 7890. Daarbij hebben we de eerste myriade aangevuld met voorloopnullen, zodat elke myriade uit vier cijfers bestaat.

Voor de eenvoud leggen we eerst uit hoe een individuele myriade omgezet wordt naar Chinese cijfers. Daarbij worden de vier cijfers van een myriade eerst elk afzonderlijk omgezet:

  1. Een cijfer 0 wordt niet omgezet. De andere cijfers worden omgezet volgens onderstaande tabel:

    Arabisch 0 1 2 3 4 5 6 7 8 9
    Chinees

    Het Chinese cijfer dat correspondeert met het Arabische cijfer 0 wordt enkel gebruikt als het volledige getal gelijk is aan nul (zie verder).

  2. De omzetting van de eerste drie cijfers (als die niet 0 zijn) wordt gevolgd door het Chinese cijfer voor de corresponderende macht van tien:

    macht ×10 ×100 ×1000
    Chinees

    Als het cijfer gelijk is aan 1 dan bestaat de omzetting enkel uit de corresponderende macht van tien.

Daarna worden de omzettingen van de individuele cijfers van een myriade samengevoegd.

Voor een getal in Arabische cijfers wordt de omzetting van elke myriade (behalve de meeste rechtse) gevolgd door het Chinese cijfer voor de corresponderende macht van tien:

macht ×104 ×108 ×1012 ×1016 ×1020 ×1024 ×1028 ×1032 ×1036 ×1040 ×1044 ×1048
Chinees

Zo wordt voor het getal 1234567890 de myriade 0012 omgezet naar 十二, de myriade 3456 naar 三千四百五十六 en de myriade 7890 naar 七千八百九十. Daarbij hebben we het Chinese cijfer voor de macht van tien die correspondeert met de myriade telkens in het rood aangeduid.

Tenslotte worden de omzettingen van de individuele myriaden samengevoegd, zodat het getal 1234567890 in Chinese cijfers wordt geschreven als 十二三千四百五十六七千八百九十.

Een myriade 0000 wordt niet omgezet, behalve als het de enige myriade is (zo krijgen we de voorstelling van het getal 0). Een myriade 0001 wordt wel omgezet, zodat 10000 bijvoorbeeld wordt omgezet naar 一.

Opgave

Definieer een klasse Japans waarmee Japanse getallen kunnen voorgesteld worden. Bij het aanmaken van Japanse getallen (Japans) moet de waarde van het getal doorgegeven worden als een natuurlijk getal $$i \in \mathbb{N}$$ (int) of als een stringvoorstelling $$s$$ (str) in Chinese cijfers. Als de gegeven waarde $$i$$ kleiner is dan nul of groter dan of gelijk aan $$10^{52}$$, de gegeven stringvoorstelling $$s$$ niet bestaat uit Chinese cijfers die voorkomen in de tabellen uit de inleiding, of als er een waarde met een ander gegevenstype wordt doorgegeven, dan moet een AssertionError opgeworpen worden met de boodschap ongeldig getal.

Zorg ervoor dat de klasse Japans de volgende statische methoden1 ondersteunt om de voorstellingen met Arabische en Chinese cijfers makkelijker naar elkaar te kunnen omzetten:

Als een Japans getal (Japans) wordt doorgegeven aan de ingebouwde functie int dan moet de decimale waarde van het getal teruggegeven worden. Als een Japans getal (Japans) wordt doorgegeven aan de ingebouwde functie str dan moet de schrijfwijze van het getal in Chinese cijfers teruggegeven worden. Analoog moet de ingebouwde functie repr een string (str) teruggeven waarvan je het formaat kan afleiden uit onderstaand voorbeeld.

Zorg ervoor dat de binaire operatoren voor de optelling (+), de aftrekking (-), de vermenigvuldiging (*), de gehele deling (//), modulo (%) en de machtsverheffing (**) telkens een nieuw Japans getal (Japans) opleveren als beide operandi Japanse getallen (Japans) zijn of als één van beide operandi een Japans getal (Japans) is en het ander een integer (int). Het resultaat van die bewerkingen moet dezelfde decimale waarde hebben als het resultaat dat deze operatoren opleveren voor twee integer operandi met dezelfde decimale waarde. Als de operator geen geldig Japans getal oplevert, dan moet een AssertionError opgeworpen worden met de boodschap ongeldig getal.

Als de zes vergelijkingsoperatoren (==, !=, <, <=, > en >=) worden toegepast op twee integers (int), dan levert dat telkens een Booleaanse waarde (bool) op. Zorg ervoor dat ze dezelfde Booleaanse waarde opleveren, als één of beide integers worden vervangen door een Japans getal (Japans) met dezelfde decimale waarde.

Voorbeeld

>>> Japans.splits_myriaden(1234567890)
['0012', '3456', '7890']
>>> Japans.myriade('0012')
'十二'
>>> Japans.myriade('3456')
'三千四百五十六'
>>> Japans.myriade('7890')
'七千八百九十'
>>> Japans.naarJapans(0)
'零'
>>> Japans.naarJapans(11)
'十一'
>>> Japans.naarJapans(17)
'十七'
>>> Japans.naarJapans(151)
'百五十一'
>>> Japans.naarJapans(302)
'三百二'
>>> Japans.naarJapans(469)
'四百六十九'
>>> Japans.naarJapans(2025)
'二千二十五'
>>> Japans.naarJapans(10000)
'一万'
>>> Japans.naarJapans(9836703)
'九百八十三万六千七百三'
>>> Japans.naarJapans(1234567890)
'十二億三千四百五十六万七千八百九十'
>>> Japans.naarJapans(2036521801)
'二十億三千六百五十二万千八百一'
>>> Japans.vanJapans('零')
0
>>> Japans.vanJapans('十一')
11
>>> Japans.vanJapans('十七')
17
>>> Japans.vanJapans('百五十一')
151
>>> Japans.vanJapans('三百二')
302
>>> Japans.vanJapans('四百六十九')
469
>>> Japans.vanJapans('二千二十五')
2025
>>> Japans.vanJapans('一万')
10000
>>> Japans.vanJapans('九百八十三万六千七百三')
9836703
>>> Japans.vanJapans('二十億三千六百五十二万千八百一')
2036521801

>>> getal1 = Japans('百二十三')
>>> int(getal1)
123
>>> str(getal1)
'百二十三'
>>> getal1
Japans('百二十三')
>>> getal1 + Japans(746)
Japans('八百六十九')
>>> 4321 + getal1
Japans('四千四百四十四')
>>> getal1 + 74822
Japans('七万四千九百四十五')
>>> getal1 - 100
Japans('二十三')
>>> 100 - getal1
Traceback (most recent call last):
AssertionError: ongeldig getal
>>> 200 - getal1
Japans('七十七')

>>> Japans(42) * Japans(983)
Japans('四万千二百八十六')
>>> 53 // Japans(17)
Japans('三')
>>> Japans(1653) % 24
Japans('二十一')
>>> Japans(23) ** Japans(5)
Japans('六百四十三万六千三百四十三')

>>> 10 == Japans('十')
True
>>> Japans(17) == 16
False
>>> Japans(17) != 16
True
>>> Japans(10) < Japans(100)
True
>>> Japans(200) <= 1000
True
>>> Japans(10) > Japans(100)
False
>>> Japans(200) >= 1000
False