Advertisement
Guest User

Day 22

a guest
Dec 23rd, 2021
1,369
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.59 KB | None | 0 0
  1. from collections import namedtuple
  2.  
  3.  
  4. def solve_part_1(instructions):
  5. res = 0
  6. grid = {}
  7.  
  8. for state, x_range, y_range, z_range in instructions:
  9. min_x, max_x = x_range
  10. min_y, max_y = y_range
  11. min_z, max_z = z_range
  12.  
  13. if min_x < -50 or max_x > 50 or min_y < -50 or max_y > 50 or min_z < -50 or max_z > 50:
  14. continue
  15.  
  16. for x in range(min_x, max_x+1):
  17. for y in range(min_y, max_y+1):
  18. for z in range(min_z, max_z+1):
  19. if state == 'off':
  20. grid[x, y, z] = 0
  21. else:
  22. grid[x, y, z] = 1
  23.  
  24. for k in grid:
  25. if grid[k] == 1:
  26. res += 1
  27.  
  28. return res
  29.  
  30. Cuboid = namedtuple('Cuboid', ['min_x', 'max_x', 'min_y', 'max_y', 'min_z', 'max_z', 'sign'])
  31.  
  32. def intersect(cuboid_1, cuboid_2):
  33. if not(cuboid_1.min_x <= cuboid_2.max_x and cuboid_1.max_x >= cuboid_2.min_x):
  34. return False
  35.  
  36. if not(cuboid_1.min_y <= cuboid_2.max_y and cuboid_1.max_y >= cuboid_2.min_y):
  37. return False
  38.  
  39. if not(cuboid_1.min_z <= cuboid_2.max_z and cuboid_1.max_z >= cuboid_2.min_z):
  40. return False
  41.  
  42. return True
  43.  
  44.  
  45. def get_intersection(cuboid_1, cuboid_2):
  46. min_x = max(cuboid_1.min_x, cuboid_2.min_x)
  47. max_x = min(cuboid_1.max_x, cuboid_2.max_x)
  48.  
  49. min_y = max(cuboid_1.min_y, cuboid_2.min_y)
  50. max_y = min(cuboid_1.max_y, cuboid_2.max_y)
  51.  
  52. min_z = max(cuboid_1.min_z, cuboid_2.min_z)
  53. max_z = min(cuboid_1.max_z, cuboid_2.max_z)
  54.  
  55. sign = cuboid_1.sign * cuboid_2.sign
  56.  
  57. if cuboid_1.sign == cuboid_2.sign:
  58. sign = -cuboid_1.sign
  59.  
  60. elif cuboid_1.sign == 1 and cuboid_2.sign == -1:
  61. sign = 1
  62.  
  63. return Cuboid(min_x, max_x, min_y, max_y, min_z, max_z, sign)
  64.  
  65.  
  66. def get_volume(cuboid):
  67. return (cuboid.max_x - cuboid.min_x + 1) * (cuboid.max_y - cuboid.min_y + 1) * (cuboid.max_z - cuboid.min_z + 1)
  68.  
  69. def solve_part_2(instructions):
  70. cuboids = []
  71. res = 0
  72.  
  73. for state, x_range, y_range, z_range in instructions:
  74. min_x, max_x = x_range
  75. min_y, max_y = y_range
  76. min_z, max_z = z_range
  77.  
  78. curr = Cuboid(min_x, max_x, min_y, max_y, min_z, max_z, -1 if state == 'off' else 1)
  79. intersections = []
  80.  
  81. for cuboid in cuboids:
  82. if intersect(curr, cuboid):
  83. intersection = get_intersection(curr, cuboid)
  84. intersections.append(intersection)
  85.  
  86. for intersection in intersections:
  87. cuboids.append(intersection)
  88.  
  89. if state == 'on':
  90. cuboids.append(curr)
  91.  
  92. res = 0
  93.  
  94. for cuboid in cuboids:
  95. res += get_volume(cuboid) * cuboid.sign
  96.  
  97. return res
  98.  
  99.  
  100. if __name__ == '__main__':
  101. with open('input_01.txt') as f:
  102. instructions = []
  103.  
  104. for line in f.readlines():
  105. line = line.strip()
  106.  
  107. state, ranges = line.split(' ')
  108. x_range, y_range, z_range = ranges.split(',')
  109.  
  110. x_range = x_range.split('=')[1]
  111. min_x, max_x = x_range.split('..')
  112. min_x, max_x = int(min_x), int(max_x)
  113.  
  114. y_range = y_range.split('=')[1]
  115. min_y, max_y = y_range.split('..')
  116. min_y, max_y = int(min_y), int(max_y)
  117.  
  118. z_range = z_range.split('=')[1]
  119. min_z, max_z = z_range.split('..')
  120. min_z, max_z = int(min_z), int(max_z)
  121.  
  122. instructions.append([state, (min_x, max_x), (min_y, max_y), (min_z, max_z)])
  123.  
  124. print(solve_part_1(instructions))
  125. print(solve_part_2(instructions))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement