Chellenge 9

Challenge 9.1


In [1]:
myinput = '/home/fmuinos/projects/adventofcode/2016/ferran/inputs/input9.txt'

In [2]:
import re

MARKER = re.compile('\(\d+x\d+\)')

def parse_line(myinput):
    with open(myinput, 'rt') as f:
        return next(f).rstrip()

def next_marker(mystr):
    marker = next(MARKER.finditer(mystr))
    return marker.group(), marker.start()

by Brute Force


In [3]:
def unzip(mystr):
    try:
        m, p = next_marker(mystr)
        a, b = map(int, m[1:-1].split('x'))
        prefix = ''
        if p > 0:
            prefix = mystr[:p]
        upper_index = p + len(m) + a
        if upper_index > len(mystr):
            upper_index = len(mystr)
        return prefix + mystr[p + len(m): upper_index] * b + unzip(mystr[upper_index:])
    except:
        return mystr

by Length Computation


In [5]:
def unzip_length(mystr):
    if MARKER.findall(mystr):
        m, p = next_marker(mystr)
        a, b = map(int, m[1:-1].split('x'))
        return p + a * b + unzip_length(mystr[p + len(m) + a:])
    else:
        return len(mystr)

Testing


In [6]:
def test(mystr):
    l = unzip_length(mystr)
    s = unzip(mystr)
    print(s[:100] + '...' * (len(s) >= 100))
    print(len(s) == l)
    print('length = {}'.format(l))

In [7]:
test('ADVENT')


ADVENT
True
length = 6

In [8]:
test('A(1x5)BC')


ABBBBBC
True
length = 7

In [9]:
test('(3x3)XYZ')


XYZXYZXYZ
True
length = 9

In [10]:
test('(6x1)(1x3)A')


(1x3)A
True
length = 6

In [11]:
test('X(8x2)(3x3)ABCY')


X(3x3)ABC(3x3)ABCY
True
length = 18

Results


In [12]:
mystr = parse_line(myinput)

In [13]:
len(unzip(mystr))


Out[13]:
110346

In [14]:
unzip_length(mystr)


Out[14]:
110346

Challenge 9.2

by Brute Force (not to be used with myinput)


In [15]:
def deep_unzip(mystr):
    while MARKER.findall(mystr):
        mystr = unzip(mystr)
    return mystr

by Length Computation


In [16]:
def deep_unzip_length(mystr):
    if MARKER.findall(mystr):
        m, p = next_marker(mystr)
        a, b = map(int, m[1:-1].split('x'))
        return p + b * deep_unzip_length(mystr[p+len(m): p+len(m)+a]) + deep_unzip_length(mystr[p+len(m)+a:])
    else:
        return len(mystr)

Testing


In [17]:
def deep_test(mystr):
    l = deep_unzip_length(mystr)
    s = deep_unzip(mystr)
    print(s[:100] + '...' * (len(s) > 100))
    print(len(s) == l)
    print('length = {}'.format(l))

In [18]:
deep_test('(6x1)(1x3)A')


AAA
True
length = 3

In [19]:
deep_test('X(8x2)(3x3)ABCY')


XABCABCABCABCABCABCY
True
length = 20

In [20]:
deep_test('(27x12)(20x12)(13x14)(7x10)(1x12)A')


AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...
True
length = 241920

Results


In [21]:
mystr = parse_line(myinput)
deep_unzip_length(mystr)


Out[21]:
10774309173