Advertisement
Guest User

Untitled

a guest
Dec 10th, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.05 KB | None | 0 0
  1. import re
  2. import functools
  3. from geometry import Point
  4.  
  5. def get_bbox(points):
  6. left, right, top, bottom = [f(getattr(p, d) for p in points) for d in "xy" for f in (min, max)]
  7. return left, right, top, bottom
  8.  
  9. def width(points):
  10. left, right, _, _ = get_bbox(points)
  11. return right - left
  12.  
  13. def display(points):
  14. left, right, top, bottom = get_bbox(points)
  15. matrix = [["." for i in range(left, right+1)] for j in range(top, bottom+1)]
  16. for p in points:
  17. matrix[p.y-top][p.x-left] = "#"
  18. print("\n".join("".join(row) for row in matrix))
  19.  
  20. def find_local_min(f, appx_x):
  21. """search around the general region of appx_t for a local minima."""
  22. f = functools.lru_cache()(f)
  23. #decide which direction to climb by examining the neighboring values of appx_t
  24. l = g(appx_x-1)
  25. m = g(appx_x)
  26. r = g(appx_x+1)
  27. if m <= r and m <= l:
  28. return appx_x
  29. elif r < m:
  30. delta = +1
  31. elif l < m:
  32. delta = -1
  33.  
  34. x = appx_x
  35. while True:
  36. if f(x) < f(x+delta):
  37. return x
  38. x += 1
  39.  
  40. points = []
  41. velocities = []
  42. with open("input10") as file:
  43. for line in file:
  44. #can't use extract_digit_sequences here because some digits are negative
  45. x,y, dx, dy = [int(x) for x in re.findall(r"-?\d+", line)]
  46. points.append(Point(x,y))
  47. velocities.append(Point(dx,dy))
  48.  
  49. #gives the coordinates of each point at time t
  50. f = lambda t: [p + v*t for p,v in zip(points, velocities)]
  51.  
  52. #heuristic 1: choose two points with different x velocities. Calculate the time at which these points have the same x coordinate. The solution is near this time.
  53. p0, v0 = min(zip(points, velocities), key=lambda t:t[1].x)
  54. p1, v1 = max(zip(points, velocities), key=lambda t:t[1].x)
  55. assert v0.x != v1.x, "heuristic fails when all points have identical x velocities"
  56. appx_t = int((p0.x - p1.x) / (v1.x - v0.x))
  57.  
  58. #heuristic 2: the solution occurs when the bounding box has the smallest width.
  59. g = lambda t: width(f(t))
  60. t = find_local_min(g, appx_t)
  61. display(f(t))
  62. print(t)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement