| @@ -1,57 +1,34 @@ | |||
| import re | |||
| def intersect(cube, other): | |||
| return not ( | |||
| cube[1] <= other[0] or | |||
| cube[0] >= other[1] or | |||
| cube[3] <= other[2] or | |||
| cube[2] >= other[3] or | |||
| cube[5] <= other[4] or | |||
| cube[4] >= other[5] | |||
| ) | |||
| def insert(cube, val): | |||
| to_break = {other for other in seen if intersect(cube, other)} | |||
| for cu in to_break: | |||
| seen.discard(cu) | |||
| xAs, xBs, yAs, yBs, zAs, zBs = zip(*{cube} | to_break) | |||
| xs = sorted(set(xAs + xBs)) | |||
| ys = sorted(set(yAs + yBs)) | |||
| zs = sorted(set(zAs + zBs)) | |||
| N = 0 | |||
| for i in range(len(xs) - 1): | |||
| for j in range(len(ys) - 1): | |||
| for k in range(len(zs) - 1): | |||
| new = (xs[i], xs[i + 1], ys[j], ys[j + 1], zs[k], zs[k + 1]) | |||
| if val == 'off' and intersect(new, cube): | |||
| seen.discard(new) | |||
| elif val == 'on' and intersect(new, cube): | |||
| seen.add(new) | |||
| elif any(intersect(old, new) for old in to_break): | |||
| seen.add(new) | |||
| def volume(xA, xB, yA, yB, zA, zB): | |||
| return abs(xB - xA) * abs(yB - yA) * abs(zB - zA) | |||
| text = open(0).read() | |||
| cubes = {} | |||
| for line in text.splitlines(): | |||
| val = line.split()[0] | |||
| xA, xB, yA, yB, zA, zB = [int(n) for n in re.findall(r'-?\d+', line)] | |||
| cubes[xA, xB + 1, yA, yB + 1, zA, zB + 1] = val | |||
| seen = set() | |||
| for i, (cube, val) in enumerate(cubes.items(), 1): | |||
| insert(cube, val) | |||
| if i == 20: | |||
| print(sum(volume(*cu) for cu in seen)) | |||
| print(sum(volume(*cu) for cu in seen)) | |||
| def net_volume(cubes): | |||
| if not cubes: | |||
| return 0 | |||
| (is_on, cube), *rest = cubes | |||
| if not is_on: | |||
| return net_volume(rest) | |||
| return volume(cube) - net_volume(intersect(cube, rest)) + net_volume(rest) | |||
| def intersect(cube, rest): | |||
| return [ | |||
| (True, new) | |||
| for _, other in rest | |||
| for new in [[f(a, b) for a, b, f in zip(cube, other, [max, min] * 3)]] | |||
| if volume(new) | |||
| ] | |||
| def volume(cube): | |||
| xA, xB, yA, yB, zA, zB = cube | |||
| return max(xB - xA + 1, 0) * max(yB - yA + 1, 0) * max(zB - zA + 1, 0) | |||
| cubes = tuple( | |||
| (line.split()[0] == 'on', [int(n) for n in re.findall(r'-?\d+', line)]) | |||
| for line in open(0).read().splitlines() | |||
| ) | |||
| print(net_volume(cubes[:20])) | |||
| print(net_volume(cubes)) | |||