Preparation

The iterator protocol1 of Python prescribes that iterable objects must support the following two methods:

iterator.__iter__()

Returns the iterable object itself. This method is required to allow both containers and iterators to be used with the for and in statements.

iterator.__next__()

Returns the next item from the iteration. If there are no further items, the StopIteration exception must be raised.

The following example shows how the class Reversed can be initialised with a sequence object (such as a string or a list). This class generates iterators that can be used to traverse the elements of the sequence object in reversed order.

class Reversed:
    
    """
    >>> for element in Reversed('python'):
    ...     print(element, end='')
    nohtyp
    >>> for element in Reversed([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

Problem description

In mathematics, the look-and-say sequence is the sequence of integers beginning as follows:

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

To generate a member of the sequence from the previous member, read off the digits of the previous member, counting the number of digits in groups of the same digit. For example:

The sequence does not necessarily need to start with the number 1. The look-and-say sequence was introduced and analyzed by John Conway in his paper "The Weird and Wonderful Chemistry of Audioactive Decay" published in Eureka 46, 5—18 in 1986.

Assignment

Define a class Conway that can be used to initialize objects with a given strict positive integer. Objects of this class are iterators that follow the iterator protocol of Python. Each iteration should return the next number from Conway's look-and-say sequence, that follows the number that was returned previously. If no number was returned previously, the number must be returned that was used to initialize the object.

Example

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

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