-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy path__init__.py
More file actions
103 lines (80 loc) · 2.31 KB
/
__init__.py
File metadata and controls
103 lines (80 loc) · 2.31 KB
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
from typing import *
from aocpy import BaseChallenge
Instruction = Tuple[str, Optional[int]]
def parse(instr: str) -> List[Instruction]:
res: List[Instruction] = []
for line in instr.strip().splitlines():
parts = line.split(" ")
if len(parts) == 1:
res.append((parts[0], None))
elif len(parts) == 2:
res.append((parts[0], int(parts[1])))
else:
raise ValueError(f"unexpected instruction length {len(parts)} for {line=}")
return res
class MachineOne:
ticks: int
acc: int
vals: List[int]
def __init__(self):
self.ticks = 0
self.acc = 1
self.vals = []
def tick(self):
self.ticks += 1
def check_acc(self):
tm = self.ticks % 40
if tm == 20:
self.vals.append(self.ticks * self.acc)
def execute(self, ins: Instruction):
(opcode, operand) = ins
if opcode == "noop":
self.tick()
self.check_acc()
elif opcode == "addx":
self.tick()
self.check_acc()
self.tick()
self.check_acc()
self.acc += operand
class MachineTwo(MachineOne):
output: str
def __init__(self):
super().__init__()
self.output = ""
def check_acc(self):
tm = self.ticks % 40
if tm == 0:
self.output += "\n"
if tm == 20:
self.vals.append(self.ticks * self.acc)
if self.acc - 1 <= tm <= self.acc + 1:
self.output += "█"
else:
self.output += " "
def execute(self, ins: Instruction):
(opcode, operand) = ins
if opcode == "noop":
self.check_acc()
self.tick()
elif opcode == "addx":
self.check_acc()
self.tick()
self.check_acc()
self.tick()
self.acc += operand
class Challenge(BaseChallenge):
@staticmethod
def one(instr: str) -> int:
inp = parse(instr)
machine = MachineOne()
for ins in inp:
machine.execute(ins)
return sum(machine.vals)
@staticmethod
def two(instr: str):
inp = parse(instr)
machine = MachineTwo()
for ins in inp:
machine.execute(ins)
return "\n" + machine.output.strip()