Search code examples
pythonsequencespython-itertools

Can anyone provide a more pythonic way of generating the morris sequence?


I'm trying to generate the morris sequence in python. My current solution is below, but I feel like I just wrote c in python. Can anyone provide a more pythonic solution?

def morris(x):
    a = ['1', '11']
    yield a[0]
    yield a[1]
    while len(a) <= x:
        s = ''
        count = 1
        al = a[-1]
        for i in range(0,len(al)):
            if i+1 < len(al) and al[i] == al[i+1]:
                count += 1
            else:
                s += '%s%s' % (count, al[i])
                count = 1
        a.append(s)
        yield s
a = [i for i in morris(30)]

Solution

  • itertools.groupby seems to fit perfectly! Just define a next_morris function as follows:

    def next_morris(number):
        return ''.join('%s%s' % (len(list(group)), digit)
                       for digit, group in itertools.groupby(str(number)))
    

    That's all!!! Look:

    print next_morris(1)
    11
    print next_morris(111221)
    312211
    

    I could use that to make a generator:

    def morris_generator(maxlen, start=1):
        num = str(start)
        while len(num) < maxlen:
            yield int(num)
            num = next_morris(num)
    

    Usage:

    for n in morris_generator(10):
        print n
    

    results:

    1
    11
    21
    1211
    111221
    312211
    13112221