12.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import itertools
  2. from math import sin, cos, radians, atan2, sqrt, pi, degrees
  3. instructions = []
  4. with open("12.input") as f:
  5. for line in f.readlines():
  6. line = line.strip()
  7. instructions.append((line[0], int(line[1:])))
  8. myadd = lambda xs,ys: tuple(x + y for x, y in zip(xs, ys))
  9. def manhattan_distance(pos):
  10. (x, y) = pos
  11. return abs(y) + abs(x)
  12. def move(position, angle, instruction):
  13. op, arg = instruction
  14. if op == 'L':
  15. angle += arg
  16. elif op == 'R':
  17. angle -= arg
  18. elif op == 'N':
  19. position = myadd(position, (0, arg))
  20. elif op == 'S':
  21. position = myadd(position, (0, -arg))
  22. elif op == 'E':
  23. position = myadd(position, (arg, 0))
  24. elif op == 'W':
  25. position = myadd(position, (-arg, 0))
  26. elif op == 'F':
  27. position = myadd(position, (cos(radians(angle)) * arg, sin(radians(angle)) * arg))
  28. return (position, angle)
  29. position = (0, 0)
  30. angle = 0
  31. for instruction in instructions:
  32. (position, angle) = move(position, angle, instruction)
  33. print("Answer 1: {:0.0f}".format(manhattan_distance(position)))
  34. def print_vector(vec):
  35. print("{}, {}".format(vec, degrees(atan2(vec[1], vec[0]))))
  36. def rotate(vec, degrees):
  37. angle = atan2(vec[1], vec[0])
  38. length = sqrt(vec[0] ** 2 + vec[1] ** 2)
  39. angle += radians(degrees)
  40. vec = (cos(angle) * length, sin(angle) * length)
  41. return vec
  42. def move_waypoint(ship_pos, way_pos, instruction):
  43. op, arg = instruction
  44. if op == 'L':
  45. way_pos = rotate(way_pos, arg)
  46. elif op == 'R':
  47. way_pos = rotate(way_pos, -arg)
  48. elif op == 'N':
  49. way_pos = myadd(way_pos, (0, arg))
  50. elif op == 'S':
  51. way_pos = myadd(way_pos, (0, -arg))
  52. elif op == 'E':
  53. way_pos = myadd(way_pos, (arg, 0))
  54. elif op == 'W':
  55. way_pos = myadd(way_pos, (-arg, 0))
  56. elif op == 'F':
  57. ship_pos = (ship_pos[0] + way_pos[0] * arg, ship_pos[1] + way_pos[1] * arg)
  58. return (ship_pos, way_pos)
  59. ship_pos = (0, 0)
  60. way_pos = (10, 1)
  61. for instruction in instructions:
  62. (ship_pos, way_pos) = move_waypoint(ship_pos, way_pos, instruction)
  63. print("Answer 2: {:0.0f}".format(manhattan_distance(ship_pos)))