advent-of-code/2022/day20.py

78 lines
1.9 KiB
Python
Raw Normal View History

2022-12-20 07:50:34 +00:00
# -*- encoding: utf-8 -*-
2022-12-22 07:20:09 +00:00
from __future__ import annotations
2022-12-20 07:50:34 +00:00
import sys
class Number:
2022-12-20 17:27:09 +00:00
current: int
2022-12-20 07:50:34 +00:00
value: int
2022-12-20 22:39:26 +00:00
def __init__(self, value: int):
self.current = 0
2022-12-20 07:50:34 +00:00
self.value = value
def __str__(self):
return str(self.value)
def __repr__(self):
return str(self)
2022-12-20 12:39:36 +00:00
def decrypt(numbers: list[Number], key: int, rounds: int) -> int:
numbers = numbers.copy()
original = numbers.copy()
2022-12-20 17:27:09 +00:00
2022-12-20 22:39:26 +00:00
for index, number in enumerate(numbers):
number.current = index
2022-12-20 12:39:36 +00:00
for _ in range(rounds):
for number in original:
2022-12-20 17:27:09 +00:00
index = number.current
offset = (number.value * key) % (len(numbers) - 1)
target = index + offset
# need to wrap
if target >= len(numbers):
target = offset - (len(numbers) - index) + 1
2022-12-20 22:39:26 +00:00
for number_2 in numbers[target:index]:
number_2.current += 1
2022-12-20 17:27:09 +00:00
2022-12-20 22:39:26 +00:00
numbers = (
numbers[:target]
+ [number]
+ numbers[target:index]
+ numbers[index + 1 :]
)
else:
for number_2 in numbers[index : target + 1]:
number_2.current -= 1
numbers = (
numbers[:index]
+ numbers[index + 1 : target + 1]
+ [number]
+ numbers[target + 1 :]
)
2022-12-20 17:27:09 +00:00
number.current = target
2022-12-20 22:39:26 +00:00
index_of_0 = next(
filter(lambda index: numbers[index].value == 0, range(len(numbers)))
)
2022-12-20 12:39:36 +00:00
return sum(
numbers[(index_of_0 + offset) % len(numbers)].value * key
for offset in (1000, 2000, 3000)
)
2022-12-20 22:39:26 +00:00
numbers = [Number(int(x)) for i, x in enumerate(sys.stdin.readlines())]
2022-12-20 12:39:36 +00:00
answer_1 = decrypt(numbers, 1, 1)
2022-12-20 07:50:34 +00:00
print(f"answer 1 is {answer_1}")
2022-12-20 12:39:36 +00:00
answer_2 = decrypt(numbers, 811589153, 10)
print(f"answer 2 is {answer_2}")