-
Notifications
You must be signed in to change notification settings - Fork 0
/
day20.py
87 lines (54 loc) · 2.04 KB
/
day20.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import pytest
from typing import *
def read_input(path: str) -> List[int]:
with open(path) as f:
return list(map(int, f.read().strip().split("\n")))
T = TypeVar("T")
def mix(xs: list[T], i: int, move: int) -> list[T]:
"""
Returns a new list in which xs[i] has been moved left or right by `move` steps.
"""
if 0 == move:
return xs
x = xs[i]
ys = xs[:i] + xs[i + 1 :]
j = (i + move) % len(ys)
return ys[:j] + [x] + ys[j:]
mix_tests = [
([1, 2, -3, 3, -2, 0, 4], 0, 1, [2, 1, -3, 3, -2, 0, 4]),
([2, 1, -3, 3, -2, 0, 4], 0, 2, [1, -3, 2, 3, -2, 0, 4]),
([1, -3, 2, 3, -2, 0, 4], 1, -3, [1, 2, 3, -2, -3, 0, 4]),
([1, 2, 3, -2, -3, 0, 4], 2, 3, [1, 2, -2, -3, 0, 3, 4]),
([1, 2, -2, -3, 0, 3, 4], 2, -2, [1, 2, -3, 0, 3, 4, -2]),
([1, 2, -3, 0, 3, 4, -2], 3, 0, [1, 2, -3, 0, 3, 4, -2]),
([1, 2, -3, 0, 3, 4, -2], 5, 4, [1, 2, -3, 4, 0, 3, -2]),
]
@pytest.mark.parametrize("_input,index,move,output", mix_tests)
def test_mix(_input, index, move, output):
assert mix(_input, index, move) == output
def mix_all(numbers: List[int], iterations: int = 1) -> List[int]:
state = list(enumerate(numbers))
for _ in range(iterations):
for i in range(len(state)):
candidate_index = next(
(
j
for j, (original_index, _) in enumerate(state)
if original_index == i
)
)
original_index, move = state[candidate_index]
state = mix(state, candidate_index, move)
return [n for i, n in state]
def coords(mixed: Iterable[int]) -> int:
zero_at = mixed.index(0)
indexes = [1000, 2000, 3000]
return sum((mixed[(zero_at + i) % len(mixed)] for i in indexes))
if __name__ == "__main__":
numbers = read_input("./day20.txt")
mixed = mix_all(numbers)
print("Part 1:", coords(mixed))
decryption_key = 811589153
print(
"Part 2:", coords(mix_all(list(map(lambda n: n * decryption_key, numbers)), 10))
)