-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathday25.py
More file actions
119 lines (89 loc) · 3.07 KB
/
day25.py
File metadata and controls
119 lines (89 loc) · 3.07 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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import re
from collections import defaultdict
from day import Day
class Rule:
def __init__(self, write, move, next_state):
self.write_value = write
self.move_direction = move
self.next_state = next_state
def execute(self, turing_machine):
turing_machine.write(self.write_value)
turing_machine.move(self.move_direction)
turing_machine.set_state(self.next_state)
class State:
REGEX = re.compile(
r''
r'In state (\w):'
r' If the current value is 0:'
r' - Write the value (\d).'
r' - Move one slot to the (\bleft\b|\bright\b).'
r' - Continue with state (\w).'
r' If the current value is 1:'
r' - Write the value (\d).'
r' - Move one slot to the (\bleft\b|\bright\b).'
r' - Continue with state (\w).'
)
def __init__(self, blueprint):
match = State.REGEX.match(blueprint)
self.label = match.group(1)
write = int(match.group(2))
move = match.group(3)
next_state = match.group(4)
rule_0 = Rule(write, move, next_state)
write = int(match.group(5))
move = match.group(6)
next_state = match.group(7)
rule_1 = Rule(write, move, next_state)
self.rules = {
0: rule_0,
1: rule_1
}
def execute(self, turing_machine):
value = turing_machine.current_value()
self.rules[value].execute(turing_machine)
class TuringMachine:
REGEX = re.compile(
r'Begin in state (\w).'
r'Perform a diagnostic checksum after (\d+) steps.'
)
def __init__(self, blueprint):
self.tape = defaultdict(int)
self.cursor = 0
self.state = None
self.steps = None
self.states = {}
self.build(blueprint)
self.execute()
def build(self, blueprint):
match = TuringMachine.REGEX.match(''.join(blueprint[:2]))
self.state = match.group(1)
self.steps = int(match.group(2))
for i in range(2, len(blueprint), 10):
state = State(''.join(blueprint[i:i+10]))
self.states[state.label] = state
def execute(self):
for _ in range(self.steps):
self.states[self.state].execute(self)
def current_value(self):
return self.tape[self.cursor]
def write(self, value):
self.tape[self.cursor] = value
def move(self, direction):
if direction == 'left':
self.cursor -= 1
elif direction == 'right':
self.cursor += 1
else:
raise ValueError('The cursor can only be moved left or right')
def set_state(self, state):
self.state = state
def diagnostic_checksum(self):
return list(self.tape.values()).count(1)
class Day25(Day):
def __init__(self, blueprint):
self.turing_machine = TuringMachine(blueprint.splitlines())
def solve_part_one(self):
return self.turing_machine.diagnostic_checksum()
def solve_part_two(self):
# There was no part two for the final puzzle!
pass