/
__init__.py
76 lines (54 loc) · 1.5 KB
/
__init__.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
from typing import *
from aocpy import BaseChallenge
from dataclasses import dataclass
@dataclass
class PositionedInteger:
value: int
position: int
def parse(instr: str) -> List[PositionedInteger]:
return [
PositionedInteger(int(x), i) for i, x in enumerate(instr.strip().splitlines())
]
def calc_new_ordinate(o: int, max_ord: int) -> int:
if o == 0:
o = max_ord
else:
o = o % max_ord
return o
def mix(inp: List[PositionedInteger]):
max_ord = len(inp) - 1
for i in range(len(inp)):
pos = 0
n: Optional[PositionedInteger] = None
while True:
if inp[pos].position == i:
n = inp[pos]
break
pos += 1
if n.value == 0:
continue
new_pos = calc_new_ordinate(pos + n.value, max_ord)
_ = inp.pop(pos)
inp.insert(new_pos, n)
def calc_answer(inp: List[PositionedInteger]) -> int:
sigma = 0
for i in range(len(inp)):
if inp[i].value == 0:
break
for n in [i + 1000, i + 2000, i + 3000]:
sigma += inp[n % len(inp)].value
return sigma
class Challenge(BaseChallenge):
@staticmethod
def one(instr: str) -> int:
inp = parse(instr)
mix(inp)
return calc_answer(inp)
@staticmethod
def two(instr: str) -> int:
inp = parse(instr)
for n in inp:
n.value *= 811589153
for _ in range(10):
mix(inp)
return calc_answer(inp)