Advertisement
Guest User

Untitled

a guest
Dec 16th, 2020
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.49 KB | None | 0 0
  1. from typing import Tuple, Dict
  2. from copy import deepcopy
  3.  
  4. inpt = open("input.txt").read().split("\n")
  5.  
  6. class Cube3D:
  7. def __init__(self, position: Tuple[int, int, int], active: bool): # position = x, y, z
  8. self.position = position
  9. self.active = active
  10. def __str__(self):
  11. return f"Cube({self.position}, {self.active})"
  12. def __repr__(self):
  13. return self.__str__()
  14. def toggle_state(self):
  15. self.active = not self.active
  16. def change_state(self, state):
  17. self.active = state
  18.  
  19. class Dimention3D:
  20. def __init__(self, inpt):
  21. self.current_cubes: Dict[Tuple[int, int, int]: Cube3D] = {(x, y, 0): Cube3D((x, y, 0), cube == "#") for y, row in enumerate(inpt) for x, cube in enumerate(row)}
  22.  
  23. self.x_vals = [0, len(inpt[0])-1] # Gives the range of x/y/z values, both are INCLUSIVE
  24. self.y_vals = [0, len(inpt)-1]
  25. self.z_vals = [0, 0]
  26.  
  27. def get_neighboring_cubes(self, position: Tuple[int, int, int]) -> set:
  28. return_cubes = set()
  29. x, y, z = position
  30.  
  31. shifts = (-1, 0, 1)
  32.  
  33. for x_change in shifts:
  34. for y_change in shifts:
  35. for z_change in shifts:
  36. if x_change == y_change == z_change == 0:
  37. continue
  38. else:
  39. try:
  40. return_cubes.add(self.current_cubes[(x+x_change, y+y_change, z+z_change)])
  41. except KeyError:
  42. pass
  43.  
  44. return return_cubes
  45.  
  46. def expand_board(self):
  47. self.x_vals[0], self.x_vals[1] = self.x_vals[0] - 1, self.x_vals[1] + 1
  48. self.y_vals[0], self.y_vals[1] = self.y_vals[0] - 1, self.y_vals[1] + 1
  49. self.z_vals[0], self.z_vals[1] = self.z_vals[0] - 1, self.z_vals[1] + 1
  50.  
  51. for x in self.x_vals:
  52. for y in range(self.y_vals[0], self.y_vals[1] + 1):
  53. for z in range(self.z_vals[0], self.z_vals[1] + 1):
  54. self.current_cubes[(x, y, z)] = Cube3D((x, y, z), False)
  55.  
  56. for y in self.y_vals:
  57. for x in range(self.x_vals[0], self.x_vals[1] + 1):
  58. for z in range(self.z_vals[0], self.z_vals[1] + 1):
  59. self.current_cubes[(x, y, z)] = Cube3D((x, y, z), False)
  60.  
  61. for z in self.z_vals:
  62. for x in range(self.x_vals[0], self.x_vals[1] + 1):
  63. for y in range(self.y_vals[0], self.y_vals[1] + 1):
  64. self.current_cubes[(x, y, z)] = Cube3D((x, y, z), False)
  65.  
  66.  
  67. def simulate_one_iteration(self):
  68. self.expand_board()
  69.  
  70. updated_dict = deepcopy(self.current_cubes)
  71.  
  72. for pos in self.current_cubes:
  73. if self.current_cubes[pos].active:
  74. if sum([neighbor.active for neighbor in self.get_neighboring_cubes(pos)]) not in (2, 3):
  75. updated_dict[pos].active = False
  76. else:
  77. if sum([neighbor.active for neighbor in self.get_neighboring_cubes(pos)]) == 3:
  78. updated_dict[pos].active = True
  79.  
  80. self.current_cubes = updated_dict
  81.  
  82. def __str__(self):
  83. return_str = ""
  84.  
  85. for z in range(self.z_vals[0], self.z_vals[1] + 1):
  86. current = ""
  87.  
  88. for y in range(self.y_vals[0], self.y_vals[1] + 1):
  89. for x in range(self.x_vals[0], self.x_vals[1] + 1):
  90.  
  91. current += "#" if self.current_cubes[(x,y,z)].active else "."
  92. current += '\n'
  93.  
  94. return_str += f"z={z}\n{current}\n"
  95. return return_str
  96.  
  97. def __repr__(self):
  98. return self.__str__()
  99.  
  100. def simulate(self):
  101. for i in range(6):
  102. self.simulate_one_iteration()
  103.  
  104. print(sum([cube.active for cube in self.current_cubes.values()]))
  105.  
  106. class Cube4D:
  107. def __init__(self, position: Tuple[int, int, int, int], active: bool): # position = x, y, z
  108. self.position = position
  109. self.active = active
  110. def __str__(self):
  111. return f"Cube({self.position}, {self.active})"
  112. def __repr__(self):
  113. return self.__str__()
  114. def toggle_state(self):
  115. self.active = not self.active
  116. def change_state(self, state):
  117. self.active = state
  118.  
  119. class Dimention4D:
  120. def __init__(self, inpt):
  121. self.current_cubes: Dict[Tuple[int, int, int, int]: Cube4D] = {(x, y, 0, 0): Cube4D((x, y, 0, 0), cube == "#") for y, row in enumerate(inpt) for x, cube in enumerate(row)}
  122.  
  123. self.x_vals = [0, len(inpt[0])-1] # Gives the range of x/y/z values, both are INCLUSIVE
  124. self.y_vals = [0, len(inpt)-1]
  125. self.z_vals = [0, 0]
  126. self.w_vals = [0, 0]
  127.  
  128. def get_neighboring_cubes(self, position: Tuple[int, int, int, int]) -> set:
  129. return_cubes = set()
  130. x, y, z, w = position
  131.  
  132. shifts = (-1, 0, 1)
  133.  
  134. for x_change in shifts:
  135. for y_change in shifts:
  136. for z_change in shifts:
  137. for w_change in shifts:
  138. if x_change == y_change == z_change == w_change == 0:
  139. continue
  140. else:
  141. try:
  142. return_cubes.add(self.current_cubes[(x+x_change, y+y_change, z+z_change, w+w_change)])
  143. except KeyError:
  144. pass
  145.  
  146. return return_cubes
  147.  
  148. def expand_board(self):
  149. self.x_vals[0], self.x_vals[1] = self.x_vals[0] - 1, self.x_vals[1] + 1
  150. self.y_vals[0], self.y_vals[1] = self.y_vals[0] - 1, self.y_vals[1] + 1
  151. self.z_vals[0], self.z_vals[1] = self.z_vals[0] - 1, self.z_vals[1] + 1
  152. self.w_vals[0], self.w_vals[1] = self.w_vals[0] - 1, self.w_vals[1] + 1
  153.  
  154.  
  155. for x in self.x_vals:
  156. for y in range(self.y_vals[0], self.y_vals[1] + 1):
  157. for z in range(self.z_vals[0], self.z_vals[1] + 1):
  158. for w in range(self.w_vals[0], self.w_vals[1] +1):
  159. self.current_cubes[(x, y, z, w)] = Cube4D((x, y, z, w), False)
  160.  
  161. for y in self.y_vals:
  162. for x in range(self.x_vals[0], self.x_vals[1] + 1):
  163. for z in range(self.z_vals[0], self.z_vals[1] + 1):
  164. for w in range(self.w_vals[0], self.w_vals[1] + 1):
  165. self.current_cubes[(x, y, z, w)] = Cube4D((x, y, z, w), False)
  166.  
  167. for z in self.z_vals:
  168. for x in range(self.x_vals[0], self.x_vals[1] + 1):
  169. for y in range(self.y_vals[0], self.y_vals[1] + 1):
  170. for w in range(self.w_vals[0], self.w_vals[1] + 1):
  171. self.current_cubes[(x, y, z, w)] = Cube4D((x, y, z, w), False)
  172.  
  173. for w in self.w_vals:
  174. for x in range(self.x_vals[0], self.x_vals[1] + 1):
  175. for y in range(self.y_vals[0], self.y_vals[1] + 1):
  176. for z in range(self.z_vals[0], self.z_vals[1] + 1):
  177. self.current_cubes[(x, y, z, w)] = Cube4D((x, y, z, w), False)
  178.  
  179.  
  180. def simulate_one_iteration(self):
  181. self.expand_board()
  182.  
  183. updated_dict = deepcopy(self.current_cubes)
  184.  
  185. for pos in self.current_cubes:
  186. if self.current_cubes[pos].active:
  187. if sum([neighbor.active for neighbor in self.get_neighboring_cubes(pos)]) not in (2, 3):
  188. updated_dict[pos].active = False
  189. else:
  190. if sum([neighbor.active for neighbor in self.get_neighboring_cubes(pos)]) == 3:
  191. updated_dict[pos].active = True
  192.  
  193. self.current_cubes = updated_dict
  194.  
  195. def __str__(self):
  196. return_str = ""
  197.  
  198. for w in range(self.w_vals[0], self.w_vals[1]+1):
  199. for z in range(self.z_vals[0], self.z_vals[1] + 1):
  200. current = ""
  201.  
  202. for y in range(self.y_vals[0], self.y_vals[1] + 1):
  203. for x in range(self.x_vals[0], self.x_vals[1] + 1):
  204. current += "#" if self.current_cubes[(x,y,z,w)].active else "."
  205. current += '\n'
  206.  
  207. return_str += f"z={z}, w={w}\n{current}\n"
  208. return return_str
  209.  
  210. def __repr__(self):
  211. return self.__str__()
  212.  
  213. def simulate(self):
  214. for i in range(6):
  215. self.simulate_one_iteration()
  216.  
  217. print(sum([cube.active for cube in self.current_cubes.values()]))
  218.  
  219. dimention3D = Dimention3D(inpt)
  220. dimention3D.simulate()
  221.  
  222. dimention4D = Dimention4D(inpt)
  223. dimention4D.simulate()
  224.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement