CoconutJJ_dmxy

Aoc Day 22

Dec 22nd, 2021
1,570
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.67 KB | None | 0 0
  1. from typing import List
  2. from sys import argv
  3. import requests
  4. import os
  5. from itertools import product
  6.  
  7.  
  8. class Cuboid:
  9.  
  10.     def __init__(self, x, y, z) -> None:
  11.         self.x = x
  12.         self.y = y
  13.         self.z = z
  14.  
  15.     def __str__(self) -> str:
  16.         return "Cube(%s,%s,%s)" % (str(self.x), str(self.y), str(self.z))
  17.  
  18.     def volume(self):
  19.  
  20.         x1, x2 = self.x
  21.         y1, y2 = self.y
  22.         z1, z2 = self.z
  23.  
  24.         return (x1 - x2 + 1) * (y1 - y2 + 1) * (z1 - z2 + 1)
  25.  
  26.     def intersect(self, i1, i2):
  27.         x, y = i1
  28.         s, t = i2
  29.  
  30.         if not (s > y or t < x):
  31.             return (max(x, s), min(y, t))
  32.         else:
  33.             return (x,y)
  34.  
  35.     def minus(self, i1, i2):
  36.         s, t = self.intersect(i1, i2)
  37.         x, y = i1
  38.  
  39.         if x <= s <= t <= y:
  40.             intervals = []
  41.  
  42.             if t != y:
  43.                 intervals.append((t + 1, y))
  44.  
  45.             if s != x:
  46.                 intervals.append((x, s - 1))
  47.  
  48.             return intervals
  49.         elif x <= s <= y and t > y:
  50.  
  51.             if s != x:
  52.                 return [(x, s - 1)]
  53.  
  54.             return []
  55.         elif s < x and x <= t <= y:
  56.             if t != y:
  57.                 return [(t + 1, y)]
  58.             return []
  59.         else:
  60.             return [(x, y)]
  61.  
  62.     def overlap(self, other: 'Cuboid'):
  63.  
  64.         x = self.intersect(self.x, other.x)
  65.         y = self.intersect(self.y, other.y)
  66.         z = self.intersect(self.z, other.z)
  67.  
  68.         return Cuboid(x, y, z)
  69.  
  70.     def subtract(self, other: 'Cuboid'):
  71.  
  72.         xs = self.minus(self.x, other.x)
  73.         ys = self.minus(self.y, other.y)
  74.         zs = self.minus(self.z, other.z)
  75.  
  76.         if max(xs, ys, zs, key=len) == 0:
  77.             return []
  78.         else:
  79.             if len(xs) == 0:
  80.                 xs.append(self.x)
  81.             if len(ys) == 0:
  82.                 ys.append(self.y)
  83.             if len(zs) == 0:
  84.                 zs.append(self.z)
  85.  
  86.         cuboids = []
  87.         for r in product(xs, ys, zs):
  88.             x,y,z = r            
  89.             cuboids.append(Cuboid(x, y, z))
  90.  
  91.         return cuboids
  92.  
  93.     def merge(self, other: 'Cuboid'):
  94.        
  95.         overlap = self.overlap(other)
  96.  
  97.         if self.x == overlap.x and self.y == overlap.y and self.z == overlap.z:
  98.             return []
  99.  
  100.         return self.subtract(other) + other.subtract(self) + [overlap]
  101.  
  102.  
  103.  
  104. def part2(lines: List[str]):
  105.  
  106.  
  107.     on_ranges = set()
  108.     off_ranges = set()
  109.  
  110.     for l in lines:
  111.  
  112.         state, ranges = l.split(" ")
  113.         axis_ranges = ranges.split(",")
  114.         x_range = axis_ranges[0].split("=")[1].split("..")
  115.         y_range = axis_ranges[1].split("=")[1].split("..")
  116.         z_range = axis_ranges[2].split("=")[1].split("..")
  117.  
  118.         x1, x2 = int(x_range[0]), int(x_range[1])
  119.         y1, y2 = int(y_range[0]), int(y_range[1])
  120.         z1, z2 = int(z_range[0]), int(z_range[1])
  121.  
  122.         if state == "on":
  123.             on_ranges.add(((x1, x2), (y1, y2), (z1, z2)))
  124.         else:
  125.             off_ranges.add(((x1, x2), (y1, y2), (z1, z2)))
  126.  
  127.     print(on_ranges)
  128.  
  129.     turned_on: list[Cuboid] = []
  130.  
  131.     for r in on_ranges:
  132.  
  133.         x, y, z = r
  134.         cube = Cuboid(x, y, z)
  135.         new = []
  136.         for t in turned_on:
  137.             new.extend(cube.merge(t))
  138.  
  139.         if len(new) == 0:
  140.             turned_on.append(cube)
  141.         else:
  142.             turned_on = new
  143.  
  144.  
  145.     for r in off_ranges:
  146.  
  147.         x, y, z = r
  148.  
  149.         cube = Cuboid(x, y, z)
  150.  
  151.         new = []
  152.  
  153.         for t in turned_on:
  154.  
  155.             new.extend(t.subtract(cube))
  156.  
  157.         turned_on = new
  158.  
  159.     total_on = 0
  160.  
  161.     for t in turned_on:
  162.         total_on += t.volume()
  163.  
  164.  
  165.     return total_on
Advertisement
Add Comment
Please, Sign In to add comment