Part 1


In [127]:
import numpy as np
from functools import reduce

In [128]:
l = ! cat input.txt | tr '\n' ';'
l = l[0].rstrip(';').split(';')
head = top-left cell tail = bottom-right cell

In [129]:
def fabrix(head, tail):
    mat = np.zeros((tail[0] + 1, tail[1] + 1))
    for i in range(head[0], tail[0] + 1):
        for j in range(head[1], tail[1] + 1):
            mat[i, j] = 1
    return mat

def parse(fid):
    left, top     = tuple(list(map(int, fid.split(' ')[2].rstrip(':').split(','))))
    width, height = tuple(list(map(int, fid.split(' ')[3].split('x'))))
    head = (left, top)
    tail = (left + width - 1, top + height - 1)
    return head, tail

def combine(mat1, mat2):
    s1, s2 = mat1.shape, mat2.shape
    big_shape = (max(s1[0], s2[0]), max(s1[1], s2[1]))
    exp1, exp2 = np.zeros(big_shape), np.zeros(big_shape)
    exp1[:s1[0],:s1[1]], exp2[:s2[0],:s2[1]] = mat1, mat2
    return exp1 + exp2

In [146]:
positions = list(map(parse, l))
mat_list = [fabrix(*pos) for pos in positions]
overlap  = reduce(combine, mat_list, np.array([[0]]))
len(overlap[overlap > 1])


Out[146]:
107663

Part 2


In [149]:
for i, s in enumerate(positions):
    c = 0
    for j in range(s[0][0], s[1][0] + 1):
        for k in range(s[0][1], s[1][1] + 1):
            c += overlap[j, k] - 1
    if c == 0:
        print(l[i])


#1166 @ 126,200: 10x11