Voorbereiding

Het iteratorprotocol1 van Python schrijft voor dat iteratorobjecten de volgende twee methoden moeten ondersteunen:

iterator.__iter__()

Geeft het iteratorobject zelf terug. Deze methode is vereist, zodat zowel samengestelde gegevenstypes als iteratoren kunnen gebruikt worden binnen for en in statements.

iterator.__next__()

Geeft het volgende element terug uit de iteratie. Indien er geen elementen meer zijn, dan moet een StopIteration uitzondering opgeworpen worden.

Onderstaand voorbeeld illustreert hoe de klasse Omgekeerd kan geïnitialiseerd worden met een sequentie-object (bijvoorbeeld een string of een lijst). Deze klasse is een iterator die kan gebruikt worden om de elementen van het sequentie-object in omgekeerde volgorde te doorlopen.

class Omgekeerd:
    
    """
    >>> for element in Omgekeerd('python'):
    ...     print(element, end='')
    nohtyp
    >>> for element in Omgekeerd([1, 2, 3, 4]):
    ...     print(element, end='')
    4321
    """
    
    def __init__(self, container):
        
        self.container = container
        self.index = len(container)
        
    def __iter__(self):
        
        return self
    
    def __next__(self):
        
        if self.index > 0:
            self.index -= 1
            return self.container[self.index]
        else:
            raise StopIteration

Probleemomschrijving

De rij van Conway2 werd geïntroduceerd door en vernoemd naar de Britse wiskundige John Conway. Het is een rij van natuurlijke getallen die als volgt begint:

1, 11, 21, 1211, 111221, 312211, 13112221, …

Het volgende element van de rij is telkens een "beschrijving" van het vorige element. Vandaar dat de rij van Conway in het Engels ook wel de look-and-say sequence genoemd wordt. We hebben dus dat

Een rij van Conway kan ook met een ander getal beginnen dan 1.

Opgave

Schrijf een klasse Conway waarvan de objecten geïnitialiseerd worden met een gegeven natuurlijk getal. Objecten van deze klasse zijn iteratoren die het iteratorprotocol van Python volgen. Bij elke iteratie wordt het natuurlijke getal uit de rij van Conway teruggegeven dat volgt op het voorgaande natuurlijke getal dat werd teruggegeven. Indien er voorheen nog geen natuurlijk getal werd teruggegeven, dan moet het getal uit de rij van Conway teruggegeven worden dat volgt op het natuurlijke getal dat werd opgegeven bij het aanmaken van het object.

Voorbeeld

>>> rij = Conway(1)
>>> next(rij)
11
>>> next(rij)
21
>>> next(rij)
1211
>>> next(rij)
111221
>>> next(rij)
312211
>>> next(rij)
13112221
>>> next(rij)
1113213211

>>> rij = Conway(333666999)
>>> next(rij)
333639
>>> next(rij)
33161319
>>> next(rij)
23111611131119