The look and say sequence is a sequence in which each number is the result of a "look and say" operation on the previous element.

Considering for example the classical version startin with `"1"`: `["1", "11", "21, "1211", "111221", ...]`. You can see that the second element describes the first as `"1(times number)1"`, the third is `"2(times number)1"` describing the second, the fourth is `"1(times number)2(and)1(times number)1"` and so on.

Your goal is to create a function which takes a starting string (not necessarily the classical `"1"`, much less a single character start) and return the nth element of the series.

## Examples

```python
look_and_say_sequence("1", 1)   == "1"
look_and_say_sequence("1", 3)   == "21"
look_and_say_sequence("1", 5)   == "111221"
look_and_say_sequence("22", 10) == "22"
look_and_say_sequence("14", 2)  == "1114"
```
Trivia: `"22"` is the only element that can keep the series constant.

Source: codewars | Difficulty: EASY
Tags: String algorithms

Fundamentals

Starter code: def look_and_say_sequence(first_element, n):
	

Solutions:
from re import sub

def look_and_say_sequence(s, n):
	for _ in range(1, n):
		s = sub('(.)\\1*', lambda m: str(len(m.group(0))) + m.group(1), s)
	return s


def look_and_say_sequence(first, n):
	result = first
	for _ in range(n - 1):
		sequence = result
		result = ''
		index = 0
		while index < len(sequence):
			pending = sequence[index]
			count = 0
			while index < len(sequence) and pending == sequence[index]:
				count += 1
				index += 1
			result += '{}{}'.format(count, pending)
	return result


from itertools import groupby
from functools import reduce

def look_and_say_sequence(first_element, n):
	return reduce(lambda s, _: ''.join(('%d%s' % (len(list(g)), n) for (n, g) in groupby(s))), range(n - 1), first_element)


look_and_say_sequence = l = lambda s, n: n > 1 and l(''.join((str(len(list(g))) + k for (k, g) in __import__('itertools').groupby(s))), n - 1) or s


from itertools import groupby

def look_and_say_sequence(e, n):
	for i in range(n - 1):
		e = ''.join((f'{len(list(grp))}{key}' for (key, grp) in groupby(e)))
	return e


import re

def look_and_say_sequence(element, n):
	return element if n == 1 else look_and_say_sequence(''.join((f'{len(e.group())}{e.group(1)}' for e in re.finditer('(\\d)\\1*', element))), n - 1)


from itertools import groupby

def look_and_say_sequence(seq, n):
	if seq == '22':
		return '22'
	for _ in range(1, n):
		seq = ''.join((f'{len(list(b))}{a}' for (a, b) in groupby(seq)))
	return seq


from itertools import groupby

def look_and_say_sequence(first_element, n):
	if first_element == '22':
		return '22'
	for _ in range(n - 1):
		first_element = ''.join((f'{len(list(l))}{c}' for (c, l) in groupby(first_element)))
	return first_element


def look_and_say_sequence(e, n):
	for i in range(1, n):
		e = look_and_say(e)
	return e

def look_and_say(e):
	(current, count, seq) = (e[0], 0, '')
	for c in e:
		if c == current:
			count += 1
		else:
			seq += f'{count}{current}'
			(count, current) = (1, c)
	return seq + f'{count}{current}'