Advertisement
Guest User

AoC 2022 - Day 20

a guest
Dec 27th, 2022
683
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.22 KB | None | 0 0
  1. """
  2. Advent of Code 2022 Day 20
  3. """
  4. import sys
  5.  
  6. from advent_tools import get_daily_input
  7.  
  8. DAY = 20
  9.  
  10. TEST = sys.argv[1] == "test" if len(sys.argv) > 1 else False
  11.  
  12. TEST_DATA = """
  13. 1
  14. 2
  15. -3
  16. 3
  17. -2
  18. 0
  19. 4
  20. """
  21.  
  22. if TEST:
  23.     def get_daily_input(_):
  24.         for line in TEST_DATA.strip().split("\n"):
  25.             yield line.strip("\n")
  26.  
  27.  
  28. class Element:
  29.     def __init__(self, value: int):
  30.         self.value = value
  31.         self.next = None
  32.         self.prev = None
  33.  
  34.  
  35. def find_answer(all_elements, zero):
  36.     answer = 0
  37.     n = zero
  38.     for _ in range(3):
  39.         for _ in range(1000 % len(all_elements)):
  40.             n = n.next
  41.         answer += n.value
  42.     return answer
  43.  
  44.  
  45. def load_elements(decryption_key: int = 1):
  46.     all_elements: list[Element] = []
  47.     zero = None
  48.     for value in get_daily_input(DAY):
  49.         curr_element = Element(int(value) * decryption_key)
  50.         if curr_element.value == 0:
  51.             zero = curr_element
  52.         if all_elements:
  53.             all_elements[-1].next = curr_element
  54.             curr_element.prev = all_elements[-1]
  55.         all_elements.append(curr_element)
  56.     all_elements[-1].next = all_elements[0]
  57.     all_elements[0].prev = all_elements[-1]
  58.     return all_elements, zero
  59.  
  60.  
  61. def mix(all_elements, passes: int = 1):
  62.     for _ in range(passes):
  63.         for e in all_elements:
  64.             steps = e.value % (len(all_elements) - 1)
  65.             if steps != 0:
  66.                 e.prev.next = e.next
  67.                 e.next.prev = e.prev
  68.  
  69.                 new_prev = e.prev
  70.                 for _ in range(steps):
  71.                     new_prev = new_prev.next
  72.  
  73.                 e.prev = new_prev
  74.                 e.next = new_prev.next
  75.                 e.prev.next = e
  76.                 e.next.prev = e
  77.  
  78.  
  79. def part_1() -> int:
  80.     all_elements, zero = load_elements()
  81.     mix(all_elements)
  82.     answer = find_answer(all_elements, zero)
  83.     return answer
  84.  
  85.  
  86. def part_2() -> int:
  87.     all_elements, zero = load_elements(decryption_key=811589153)
  88.     mix(all_elements, passes=10)
  89.     answer = find_answer(all_elements, zero)
  90.     return answer
  91.  
  92.  
  93. def main():
  94.     print(f"Part 1: {part_1()}")
  95.     print(f"Part 2: {part_2()}")
  96.  
  97.  
  98. if __name__ == "__main__":
  99.     main()
  100.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement