Solutions to Advent of Code 2017 https://adventofcode.com/2017/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

20.py 1.7KB

12345678910111213141516171819202122232425262728293031323334353637
  1. import operator
  2. import re
  3. from collections import defaultdict
  4. POS, VEL, ACC = 0, 1, 2
  5. with open('data/20.txt') as file:
  6. pattern = re.compile(r'<(.*?),(.*?),(.*?)>')
  7. particles = list([list(map(int, part)) for part in pattern.findall(line)] for line in file.readlines())
  8. # Part one: I'm not sure this will work for all inputs. This is just a rough approximation
  9. # based on the fastest acceleration and then velocity. It's possible that some input will
  10. # have multiple particles with the same acceleration and velocity, or that a higher
  11. # velocity will be better as it works against the acceleration. It should probably be
  12. # simulated fully, instead.
  13. # Acceleration will always win out in the long run
  14. min_acc = min(sum(map(abs, p[ACC])) for p in particles)
  15. slowest = [(i, p) for i, p in enumerate(particles) if sum(map(abs, p[ACC])) == min_acc]
  16. # Tie-break using velocity...
  17. print(f'Part one: {min(slowest, key=lambda indexed: sum(map(abs, indexed[1][VEL])))[0]}')
  18. last_collision = 0
  19. while last_collision < 1000: # Assume if we don't collide in 1k iterations, we'll never collide
  20. last_collision += 1
  21. positions = defaultdict(list)
  22. for i, particle in enumerate(particles):
  23. particle[VEL] = list(map(operator.add, particle[VEL], particle[ACC]))
  24. particle[POS] = list(map(operator.add, particle[POS], particle[VEL]))
  25. pos_key = ','.join(map(str, particle[POS]))
  26. positions[pos_key].append(particle)
  27. for overlaps in positions.values():
  28. if len(overlaps) > 1:
  29. particles = [p for p in particles if p not in overlaps]
  30. last_collision = 0
  31. print(f'Part two: {len(particles)}')