import itertools lines = open("input.txt", "r").read().splitlines() drops = set() for line in lines: drop = line.split(",") drop = (int(drop[0]), int(drop[1]), int(drop[2])) drops.add(drop) def check_adjacent(drop, drops): pos = ((0, 0, 1), (0, 1, 0), (1, 0, 0), (0, 0, -1), (0, -1, 0), (-1, 0, 0)) sides = 6 for p in pos: if (drop[0] + p[0], drop[1] + p[1], drop[2] + p[2]) in drops: sides -= 1 return sides def get_dims(drops): maxx, maxy, maxz = -1, -1, -1 minx, miny, minz = 9999, 9999, 9999 for drop in drops: if drop[0] > maxx: maxx = drop[0] if drop[0] < minx: minx = drop[0] if drop[1] > maxy: maxy = drop[1] if drop[1] < miny: miny = drop[1] if drop[2] > maxz: maxz = drop[2] if drop[2] < minz: minz = drop[2] return maxx, maxy, maxz, minx, miny, minz def generate_full_cube(drops): dims = get_dims(drops) maxdims = [x + 2 for x in dims[:3]] mindims = [x - 2 for x in dims[3:]] ranges = [range(x, y + 1) for x, y in zip(mindims, maxdims)] return set(itertools.product(*ranges)) def steam(drops): dims = get_dims(drops) maxdims = [x + 2 for x in dims[:3]] mindims = [x - 2 for x in dims[3:]] start = tuple((x - 1 for x in maxdims)) visited = set() rim = set() pos = ((0, 0, 1), (0, 1, 0), (1, 0, 0), (0, 0, -1), (0, -1, 0), (-1, 0, 0)) free = {start} while len(free) > 0: current = free.pop() visited.add(current) for p in pos: n = (current[0] + p[0], current[1] + p[1], current[2] + p[2]) if n in drops: rim.add(n) elif ( maxdims[0] >= n[0] >= mindims[0] and maxdims[1] >= n[1] >= mindims[1] and maxdims[2] >= n[2] >= mindims[2] and n not in visited ): free.add(n) return visited steam = steam(drops) cube = generate_full_cube(drops) air = cube.symmetric_difference(steam.union(drops)) b = 0 for c in air: b += 6 - (check_adjacent(c, drops)) s = 0 for d in drops: s += check_adjacent(d, drops) print(s - b)