DEV Community 👩‍💻👨‍💻

Cover image for AoC 2015 - Day 10 - I give in to RegEx
Jules
Jules

Posted on

AoC 2015 - Day 10 - I give in to RegEx

Lovely example of the Look-and-Say Number Sequence in puzzle form today. We're given a longer example in the puzzle, but the basic idea is that we have a sequence of numbers like this: 3111

This is transformed into the next number in the series by 'saying what we see', one three, three ones: 1331

Which becomes one one, two threes, one one: 112311

And so on. Here's how it's described in Part 1 of the puzzle:

Screenshot of Advent of Code puzzle

To split up the slightly longer puzzle input, I did think briefly about creating a regular expression, but couldn't find a way to select groups of digits that also included a group of only one digit. Instead of digging deeper into RegEx, I bailed and coded a loop:

groups = []
buffer = ''
for c in puzzle_input:
    if buffer == '':
        buffer += c
    else:
        if c == buffer[0]:
            buffer += c
        else:
            groups.append(buffer)
            buffer = c
groups.append(buffer)
Enter fullscreen mode Exit fullscreen mode

I went on to solve Part 1, but the above sat really badly with me when I knew it could probably be done in a single line, confirmed when I browsed through the Reddit megathread. A couple of the solutions there used the expression ((\d)\2*) which I explored on the great site RegExr.com. As well as letting you test regular expressions on your own text, it also provides an explanation in words of what your expression is doing:

Description of regular expression from RegExr.com

This explanation is for the above regular expression, and is starting to sort of make sense to me... In any case, it does make Part 1 fairly straightforward:

regex = re.compile(r'((\d)\2*)')

def translate(work_string):
    groups = [i[0] for i in regex.findall(work_string)]
    new_string = ''
    for group in groups:
        #First we 'say' how many of each digit there is, with len()
        #followed by the digit itself
        new_string += str(len(group)) + group[0]
    return new_string

#Part 1 -- forty rounds
for i in range(40):
    work_string = translate(work_string)
print(len(work_string))
Enter fullscreen mode Exit fullscreen mode

The translate() function started off in-line, but had to go into a function because of Part 2:

Screenshot of Advent of Code puzzle

Thanks to having translate() in a function, Part 2 is as easy as this:

#Part 2 -- another ten rounds
for i in range(10):
    work_string = translate(work_string)
print(len(work_string))
Enter fullscreen mode Exit fullscreen mode

... and waiting for some very long strings to be parsed.

More fun was watching John Conway talk about the 'look and say' series, which I've embedded below — enjoy!

Top comments (0)

🌚 Friends don't let friends browse without dark mode.

Sorry, it's true.