20.py 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. lines = [int(line) for line in open("20.input")]
  2. def show(nxt):
  3. start = 0
  4. current = start
  5. while True:
  6. print(lines[current], " ", end="")
  7. current = nxt[current]
  8. if current == start:
  9. break
  10. print("")
  11. full_circ = len(lines) - 1
  12. def mix(lines, repeat=1):
  13. nxt = {i: i+1 for i in range(len(lines)-1)}
  14. nxt[len(lines)-1] = 0
  15. prev = {v: k for k, v in nxt.items()}
  16. for i in range(repeat):
  17. print("Iteration", i + 1)
  18. for num, val in enumerate(lines):
  19. if val > 0:
  20. target = num
  21. for i in range(val % full_circ):
  22. target = nxt[target]
  23. if target == num:
  24. continue
  25. nxt[prev[num]] = nxt[num]
  26. tmp_nxt = nxt[target]
  27. nxt[target] = num
  28. nxt[num] = tmp_nxt
  29. prev = {v: k for k, v in nxt.items()}
  30. elif val < 0:
  31. target = num
  32. for i in range((-val) % full_circ):
  33. target = prev[target]
  34. if target == num:
  35. continue
  36. prev[nxt[num]] = prev[num]
  37. tmp_prev = prev[target]
  38. prev[target] = num
  39. prev[num] = tmp_prev
  40. nxt = {v: k for k, v in prev.items()}
  41. #show(nxt)
  42. total = 0
  43. current = max(i for i, v in enumerate(lines) if v == 0)
  44. for i in range(1, 3001):
  45. current = nxt[current]
  46. if i % 1000 == 0:
  47. total += lines[current]
  48. return total
  49. print("Part 1:", mix(lines, 1))
  50. print("Part 2:", mix([811589153 * x for x in lines], 10))