Advertisement
Guest User

Untitled

a guest
Dec 11th, 2018
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.65 KB | None | 0 0
  1. import re
  2. import sys
  3. from collections import Counter
  4.  
  5.  
  6. class BoundingBox:
  7. """
  8. A 2D bounding box
  9. """
  10.  
  11. def __init__(self, points):
  12. if len(points) == 0:
  13. raise ValueError("Can't compute bounding box of empty list")
  14. self.min_x = sys.maxsize
  15. self.min_y = sys.maxsize
  16. self.max_x = -1
  17. self.max_y = -1
  18. for p in points:
  19. x = p.x
  20. y = p.y
  21. if x < self.min_x:
  22. self.min_x = x
  23. if y < self.min_y:
  24. self.min_y = y
  25. if x > self.max_x:
  26. self.max_x = x
  27. elif y > self.max_y:
  28. self.max_y = y
  29.  
  30. @property
  31. def width(self):
  32. return self.max_x - self.min_x
  33.  
  34. @property
  35. def height(self):
  36. return self.max_y - self.min_y
  37.  
  38. def __repr__(self):
  39. return "BoundingBox({}, {}, {}, {})".format(
  40. self.min_x, self.max_x, self.min_y, self.max_y
  41. )
  42.  
  43. def contains(self, point):
  44. return self.min_x <= point.x <= self.max_x and self.min_y <= point.y <= self.max_y
  45.  
  46.  
  47. class Point:
  48. def __init__(self, x, y, xv, yv):
  49. self.x = x
  50. self.y = y
  51. self.xv = xv
  52. self.yv = yv
  53.  
  54. def update(self, step_size):
  55. self.x += self.xv * step_size
  56. self.y += self.yv * step_size
  57.  
  58. def __eq__(self, other):
  59. """Overrides the default implementation"""
  60. if isinstance(other, Point):
  61. return (
  62. self.x == other.x
  63. and self.y == other.y
  64. and self.xv == other.xv
  65. and self.yv == other.yv
  66. )
  67. return NotImplemented
  68.  
  69. def __str__(self):
  70. return f"{self.x},{self.y} - {self.xv}, {self.yv}"
  71.  
  72. def __repr__(self):
  73. return f"Point({self.x}, {self.y}, {self.xv}, {self.yv})"
  74.  
  75.  
  76. def parse_line(line):
  77. parsed = list(map(int, re.findall(r"[-\d]+", line)))
  78. return parsed[0], parsed[1], parsed[2], parsed[3]
  79.  
  80.  
  81. def step(points, step_size, grid_bb):
  82. remove_points = []
  83. for point in points:
  84. point.update(step_size)
  85. if not grid_bb.contains(point):
  86. remove_points.append(point)
  87.  
  88. for remove_point in remove_points:
  89. points.remove(remove_point)
  90.  
  91.  
  92. def draw(points, time):
  93. print(time)
  94. bb = BoundingBox(points)
  95. for y in range(bb.min_y, bb.max_y + 1):
  96. for x in range(bb.min_x, bb.max_x + 1):
  97. if any(point.x == x and point.y == y for point in points):
  98. print("#", end="")
  99. else:
  100. print(".", end="")
  101.  
  102. print()
  103. print()
  104.  
  105.  
  106. points = []
  107.  
  108. with open("input.txt") as fh:
  109. for line in fh:
  110. x, y, xv, yv = parse_line(line)
  111. points.append(Point(x, y, xv, yv))
  112.  
  113. grid_bb = BoundingBox(points)
  114.  
  115. # normalize
  116. x_add = abs(grid_bb.min_x)
  117. y_add = abs(grid_bb.min_y)
  118.  
  119. for p in points:
  120. p.x += x_add
  121. p.y += y_add
  122.  
  123. grid_bb = BoundingBox(points)
  124.  
  125. time = 0
  126. step_size = 1
  127. keep_simulating = True
  128.  
  129.  
  130. def is_interesting(points):
  131. if points and len(points) > 10:
  132. bb = BoundingBox(points)
  133. if bb.width < 100:
  134. x_counter = Counter()
  135. for point in points:
  136. x_counter.update(str(point.x))
  137. total_x_same = sum(0 if total < 6 else 1 for total in x_counter.values())
  138. if total_x_same > 3:
  139. return True
  140.  
  141. return False
  142.  
  143.  
  144. while keep_simulating:
  145. step(points, step_size, grid_bb)
  146. if not points:
  147. keep_simulating = False
  148.  
  149. if is_interesting(points):
  150. draw(points, time + 1)
  151.  
  152. time += step_size
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement