#!/usr/bin/env python3 from pathlib import Path from collections import Counter def part_1(input): result = 0 cubes = Counter() for line in input: cmd, cube = line.rstrip().split() x, y, z = cube.split(',') xn_min, xn_max = [int(c) for c in x.split('=')[1].split('..')] yn_min, yn_max = [int(c) for c in y.split('=')[1].split('..')] zn_min, zn_max = [int(c) for c in z.split('=')[1].split('..')] xn_min = xn_min if xn_min > -50 else -50 xn_max = xn_max if xn_max < 51 else 51 yn_min = yn_min if yn_min > -50 else -50 yn_max = yn_max if yn_max < 51 else 51 zn_min = zn_min if zn_min > -50 else -50 zn_max = zn_max if zn_max < 51 else 51 sn = 1 if 'on' == cmd else -1 if xn_max < xn_min or yn_max < yn_min or zn_max < zn_min: continue update = Counter() for (xi_min, xi_max, yi_min, yi_max, zi_min, zi_max), si in cubes.items(): x_min = xn_min if xn_min > xi_min else xi_min x_max = xn_max if xn_max < xi_max else xi_max y_min = yn_min if yn_min > yi_min else yi_min y_max = yn_max if yn_max < yi_max else yi_max z_min = zn_min if zn_min > zi_min else zi_min z_max = zn_max if zn_max < zi_max else zi_max if x_min <= x_max and y_min <= y_max and z_min <= z_max: update[(x_min, x_max, y_min, y_max, z_min, z_max)] -= si if sn > 0: update[(xn_min, xn_max, yn_min, yn_max, zn_min, zn_max)] += sn cubes.update(update) to_delete = [] for c in cubes: if not cubes[c]: to_delete.append(c) for d in to_delete: del cubes[d] result = sum((x1 - x0 + 1) * (y1 - y0 + 1) * (z1 - z0 + 1) * sgn for (x0, x1, y0, y1, z0, z1), sgn in cubes.items()) print("Part 1 result:", result) def part_2(input): result = 0 cubes = Counter() for line in input: cmd, cube = line.rstrip().split() x, y, z = cube.split(',') xn_min, xn_max = [int(c) for c in x.split('=')[1].split('..')] yn_min, yn_max = [int(c) for c in y.split('=')[1].split('..')] zn_min, zn_max = [int(c) for c in z.split('=')[1].split('..')] sn = 1 if 'on' == cmd else -1 update = Counter() for (xi_min, xi_max, yi_min, yi_max, zi_min, zi_max), si in cubes.items(): x_min = xn_min if xn_min > xi_min else xi_min x_max = xn_max if xn_max < xi_max else xi_max y_min = yn_min if yn_min > yi_min else yi_min y_max = yn_max if yn_max < yi_max else yi_max z_min = zn_min if zn_min > zi_min else zi_min z_max = zn_max if zn_max < zi_max else zi_max if x_min <= x_max and y_min <= y_max and z_min <= z_max: update[(x_min, x_max, y_min, y_max, z_min, z_max)] -= si if sn > 0: update[(xn_min, xn_max, yn_min, yn_max, zn_min, zn_max)] += sn cubes.update(update) to_delete = [] for c in cubes: if not cubes[c]: to_delete.append(c) for d in to_delete: del cubes[d] result = sum((x1 - x0 + 1) * (y1 - y0 + 1) * (z1 - z0 + 1) * sgn for (x0, x1, y0, y1, z0, z1), sgn in cubes.items()) print("Part 2 result:", result) input = list() p = Path(__file__).with_name('input.txt') with open(p) as f: input = f.readlines() part_1(input) part_2(input)