-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathp11.py
73 lines (61 loc) · 2.25 KB
/
p11.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
from collections import defaultdict
from aocd import data
from p09 import Boost
class Robot(Boost):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.hull = defaultdict(int)
self.pos = 0j
self.direction = 0
self.need_color = True
self.movement = {
0: {0: (-1, 3), 1: (1, 1)}, # facing up, move left or right
1: {0: (-1j, 0), 1: (1j, 2)}, # facing right, move up or down
2: {0: (1, 1), 1: (-1, 3)}, # facing down, move right or left
3: {0: (1j, 2), 1: (-1j, 0)}, # facing left, move down or up
}
def _move(self, rotation):
travel, new_direction = self.movement[self.direction][rotation]
self.direction = new_direction
self.pos += travel
def execute(self):
while (code := self._get_op_code()).value != 99:
arg1, arg2, arg3 = self._get_args(code)
op = self._get_op(code.op)
if code.op == 3:
op(arg1, str(self.hull[self.pos]))
elif code.op == 4:
self.pointer += 2
if self.need_color:
# paint current panel
self.hull[self.pos] = arg1.value
self.need_color = False
else:
# get rotation for next position
# and then move to it
rotation = arg1.value
self._move(rotation)
self.need_color = True
else:
op(arg1, arg2, arg3, None)
if __name__ == '__main__':
program = [code for code in data.split(',')] + ['0']*1000
robot = Robot(program)
robot.execute()
print('Part 1:', len(robot.hull))
robot = Robot(program)
# initial starting panel
# must be painted white
robot.hull[robot.pos] = 1
robot.execute()
height = max(robot.hull.keys(), key=lambda p: p.imag).imag
width = max(robot.hull.keys(), key=lambda p: p.real).real
print('Part 2:')
for y in range(int(height)+1):
for x in range(int(width)+1):
p = complex(x,y)
if robot.hull[p] == 1:
print('#', end='')
else:
print(' ', end='')
print()