Paul Mouzas

home

Look and Say Sequence

16 Sep 2014

Here was a fun little exerscise on Reddit’s daily programmer.

#Description The Look and Say sequence is an interesting sequence of numbers where each term is given by describing the makeup of the previous term. The 1st term is given as 1. The 2nd term is 11 (‘one one’) because the first term (1) consisted of a single 1. The 3rd term is then 21 (‘two one’) because the second term consisted of two 1s. The first 6 terms are: 1 11 21 1211 111221 312211 #Formal Inputs & Outputs ##Input On console input you should enter a number N ##Output The Nth Look and Say number. #Bonus Allow any ‘seed’ number, not just 1. Can you find any interesting cases?

Instead of getting the input from the console, I will just be including it in the script. And instead of returning the Nth Look and Say number, I return the entire sequence up to N.

import unittest
from itertools import groupby

TERM = '23'
N = 10

def next_term(term):
    output = ''
    for k, g in groupby(term):
        first = str(len(list(g)))
        second = k
        output += (first + second)
    return output

def look_n_say(n, term):
    output = []
    for i in range(n):
        output.append(term)
        term = next_term(term)
    return output

class LookNSayTest(unittest.TestCase):
    def setUp(self):
        self.expected = ['23', '1213', '11121113', '31123113', '132112132113',
                    '11131221121113122113', '311311222112311311222113', 
                    '1321132132211213211321322113', 
                    '11131221131211132221121113122113121113222113', 
                    '3113112221131112311332211231131122211311123113322113']
        self.got = look_n_say(N, TERM)
                    
    def test_seq(self):
        self.assertEqual(self.got, self.expected)
    
if __name__ == '__main__':
    unittest.main()

I used the groupby function in Python’s itertools module to return consecutive keys and groups from the term. For example, with the term ‘233311’:

[k for k, g in groupby('233311')] --> 2 3 1
[list(g) for k, g in groupby('233311')] --> 2 333 11