In [1]:
#!/usr/bin/env
from cStringIO import StringIO

def decompress_len_shallow(input_str):
    return sum(decomp_len_iter(input_str.replace(' ',''), False))

def decompress_len_deep(input_str):
    return sum(decomp_len_iter(input_str.replace(' ',''), True))

def decomp_len_iter(input_str, deep_decompression):
    # Should really use a single bytearray here and pass it into recursive calls
    # Pre-optimization is the root of all evil, and recreating is the quickest/simplest way for now.
    s = StringIO(input_str)
    s.seek(0)
    while True:
        char = s.read(1)
        if char == '(':
            repeat_cmd = [char]
            while not repeat_cmd[-1] == ')':
                repeat_cmd.append(s.read(1))
            charnum, count = ''.join(repeat_cmd[1:-1]).split('x')
            if deep_decompression:
                yield sum(decomp_len_iter(s.read(int(charnum)), deep_decompression)) * int(count)
            else:
                yield len(s.read(int(charnum))) * int(count)
        elif char == '':
            return
        else:
            yield 1

In [2]:
assert decompress_len_shallow('ADVENT') == 6
assert decompress_len_shallow('A(1x5)BC') == 7
assert decompress_len_shallow('(3x3)XYZ') == 9
assert decompress_len_shallow('A(2x2)BCD(2x2)EFG') == 11
assert decompress_len_shallow('(6x1)(1x3)A') == 6
assert decompress_len_shallow('X(8x2)(3x3)ABCY') == 18
print "Puzzle 1 Examples Success"
assert decompress_len_deep('(3x3)XYZ') == 9
assert decompress_len_deep('X(8x2)(3x3)ABCY') == 20
assert decompress_len_deep('(27x12)(20x12)(13x14)(7x10)(1x12)A') == 241920
assert decompress_len_deep('(25x3)(3x3)ABC(2x3)XY(5x2)PQRSTX(18x9)(3x2)TWO(5x7)SEVEN') == 445
print "Puzzle 2 Examples Success"


Puzzle 1 Examples Success
Puzzle 2 Examples Success

In [3]:
print "Puzzle 1 Solution"
with open('Dec9.input', 'r') as f:
    print decompress_len_shallow(f.read())


Puzzle 1 Solution
115118

In [4]:
print "Puzzle 2 Solution"
with open('Dec9.input', 'r') as f:
    print decompress_len_deep(f.read())


Puzzle 2 Solution
11107527530