-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday24.py
107 lines (80 loc) · 2.54 KB
/
day24.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#!/usr/bin/env python3
from functools import cache
def parse_input():
with open("./input") as f:
lines = f.readlines()
instruction_blocks = []
new_block = []
for line in lines:
instr = line.strip().split(" ")
if instr[0] == "inp":
if len(new_block) > 0:
instruction_blocks.append(new_block)
new_block = []
else:
new_block.append(instr)
instruction_blocks.append(new_block)
return instruction_blocks
def process(instr_idx, w, z):
variables = [w, 0, 0, z]
var_indices = "wxyz"
for instr in instructions[instr_idx]:
op, a, b = instr
var_idx = var_indices.index(a)
b_val = variables[var_indices.index(b)] if b.isalpha() else int(b)
match op:
case "add":
variables[var_idx] += b_val
case "mul":
variables[var_idx] *= b_val
case "div":
assert b_val != 0
variables[var_idx] = int(variables[var_idx] / b_val)
case "mod":
assert variables[var_idx] >= 0 and b_val > 0
variables[var_idx] = variables[var_idx] % b_val
case "eql":
variables[var_idx] = 1 if variables[var_idx] == b_val else 0
return variables[var_indices.index("z")]
min_model_num = ""
max_model_num = ""
def part1():
@cache
def find_model_num(idx, cur_z):
if cur_z >= 1000000:
return False
global max_model_num
if idx == len(instructions):
if cur_z == 0:
return True
return False
for w in range(9, 0, -1):
max_model_num += str(w)
if find_model_num(idx + 1, process(idx, w, cur_z)):
return True
max_model_num = max_model_num[:-1]
return False
find_model_num(0, 0)
def part2():
@cache
def find_model_num(idx, cur_z):
if cur_z >= 1000000:
return False
global min_model_num
if idx == len(instructions):
if cur_z == 0:
return True
return False
for w in range(1, 10):
min_model_num += str(w)
if find_model_num(idx + 1, process(idx, w, cur_z)):
return True
min_model_num = min_model_num[:-1]
return False
find_model_num(0, 0)
if __name__ == "__main__":
instructions = parse_input()
part1()
print(f"part1: {max_model_num}")
part2()
print(f"part2: {min_model_num}")