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.

16.py 1.4KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. import string
  2. from functools import partial
  3. def spin(amount, line):
  4. return line[-amount:] + line[:-amount]
  5. def exchange(p1, p2, line):
  6. line[p1], line[p2] = line[p2], line[p1]
  7. return line
  8. def partner(n1, n2, line):
  9. p1, p2 = line.index(n1), line.index(n2)
  10. line[p1], line[p2] = line[p2], line[p1]
  11. return line
  12. def dance(reps, moves):
  13. line = list(string.ascii_lowercase[:16])
  14. # Maintain a history to try and find cycles. If we ever generate the same line twice
  15. # then all of the remainder will just cycle between those two lines.
  16. history = []
  17. for i in range(reps):
  18. for move in moves:
  19. line = move(line)
  20. if line in history:
  21. start = history.index(line)
  22. cycle = len(history) - start
  23. return ''.join(history[start + (reps - i - 1) % cycle])
  24. history.append(line[:]) # NB: Copy of the line, so it doesn't get mutated next cycle...
  25. return ''.join(line)
  26. instructions = {
  27. 's': lambda r: partial(spin, int(r)),
  28. 'x': lambda r: partial(exchange, *map(int, r.split('/'))),
  29. 'p': lambda r: partial(partner, *r.split('/'))
  30. }
  31. with open('data/16.txt', 'r') as file:
  32. # Pre-parse the list of moves into function calls to save string-fiddling lots of times
  33. moves = list(map(lambda line: instructions[line[0]](line[1:]), file.readline().strip().split(',')))
  34. print(f'Part one: {dance(1, moves)}')
  35. print(f'Part two: {dance(1000000000, moves)}')