from collections import defaultdict from tools.aoc import AOCDay from tools.coordinate import Coordinate, Cube from typing import Any class Day(AOCDay): inputs = [ [ (39, "test_input22_1_0"), (590784, "test_input22_1_1"), (570915, "input22") ], [ (2758514936282235, "test_input22_2_0"), (1268313839428137, "input22") ] ] def getCubeList(self, part1: bool = False): for line in self.getInput(): state, c = line.split() co = c.split(",") _, xco = co[0].split("=") _, yco = co[1].split("=") _, zco = co[2].split("=") minX, maxX = map(int, xco.split("..")) minY, maxY = map(int, yco.split("..")) minZ, maxZ = map(int, zco.split("..")) new_cube = Cube(Coordinate(minX, minY, minZ), Coordinate(maxX, maxY, maxZ)) if not part1 \ or (new_cube.top_left >= Coordinate(-50, -50, -50) and new_cube.bottom_right <= Coordinate(50, 50, 50)): yield state == "on", new_cube def getOnSum(self, part1: bool = False) -> int: cubes = defaultdict(int) for switch_state, this_cube in self.getCubeList(part1=part1): for prior_cube in cubes.copy(): intersect_cube = this_cube.intersection(prior_cube) if intersect_cube: cubes[intersect_cube] -= cubes[prior_cube] if switch_state: cubes[this_cube] = 1 return sum(len(cube) * on_off for cube, on_off in cubes.items()) def part1(self) -> Any: return self.getOnSum(part1=True) def part2(self) -> Any: return self.getOnSum() if __name__ == '__main__': day = Day(2021, 22) day.run(verbose=True)