Skip to content

Commit 7b91f98

Browse files
committed
Added day 2018-16
1 parent 8ae0a42 commit 7b91f98

File tree

1 file changed

+207
-0
lines changed

1 file changed

+207
-0
lines changed

2018/16-Chronal Classification.py

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
# -------------------------------- Input data ---------------------------------------- #
2+
import os
3+
4+
test_data = {}
5+
6+
test = 1
7+
test_data[test] = {
8+
"input": """Before: [3, 2, 1, 1]
9+
9 2 1 2
10+
After: [3, 2, 2, 1]""",
11+
"expected": ["Unknown", "Unknown"],
12+
}
13+
14+
test = "real"
15+
input_file = os.path.join(
16+
os.path.dirname(__file__),
17+
"Inputs",
18+
os.path.basename(__file__).replace(".py", ".txt"),
19+
)
20+
test_data[test] = {
21+
"input": open(input_file, "r+").read().strip(),
22+
"expected": ["Unknown", "Unknown"],
23+
}
24+
25+
# -------------------------------- Control program execution ------------------------- #
26+
27+
case_to_test = "real"
28+
part_to_test = 2
29+
30+
# -------------------------------- Initialize some variables ------------------------- #
31+
32+
puzzle_input = test_data[case_to_test]["input"]
33+
puzzle_expected_result = test_data[case_to_test]["expected"][part_to_test - 1]
34+
puzzle_actual_result = "Unknown"
35+
36+
37+
# -------------------------------- Actual code execution ----------------------------- #
38+
39+
registers = [0] * 4
40+
41+
i = 0
42+
file_contents = puzzle_input.splitlines()
43+
nb_lines = len(file_contents)
44+
45+
more_than_3_opcodes = 0
46+
opcodes_mapping = {i: [] for i in range(16)}
47+
while i < nb_lines:
48+
if file_contents[i] == "":
49+
i += 1
50+
continue
51+
elif file_contents[i][:4] != "Befo":
52+
i += 1
53+
continue
54+
55+
test_program = file_contents[i + 6 :]
56+
57+
before, operation, after = file_contents[i : i + 3]
58+
59+
numeric_opcode = int(operation.split(" ")[0])
60+
a, b, c = map(int, operation.split(" ")[1:])
61+
62+
init = before[9:-1].split(", ")
63+
init = [int(x) for x in init]
64+
65+
final = after[9:-1].split(", ")
66+
final = [int(x) for x in final]
67+
68+
matching_opcodes = []
69+
70+
for opcode in [
71+
"addr",
72+
"addi",
73+
"mulr",
74+
"muli",
75+
"banr",
76+
"bani",
77+
"borr",
78+
"bori",
79+
"setr",
80+
"seti",
81+
"gtir",
82+
"gtri",
83+
"gtrr",
84+
"eqir",
85+
"eqri",
86+
"eqrr",
87+
]:
88+
registers = init.copy()
89+
90+
if opcode == "addr":
91+
registers[c] = registers[a] + registers[b]
92+
elif opcode == "addi":
93+
registers[c] = registers[a] + b
94+
95+
elif opcode == "mulr":
96+
registers[c] = registers[a] * registers[b]
97+
elif opcode == "muli":
98+
registers[c] = registers[a] * b
99+
100+
elif opcode == "banr":
101+
registers[c] = registers[a] & registers[b]
102+
elif opcode == "bani":
103+
registers[c] = registers[a] & b
104+
105+
elif opcode == "borr":
106+
registers[c] = registers[a] | registers[b]
107+
elif opcode == "bori":
108+
registers[c] = registers[a] | b
109+
110+
elif opcode == "setr":
111+
registers[c] = registers[a]
112+
elif opcode == "seti":
113+
registers[c] = a
114+
115+
elif opcode == "gtir":
116+
registers[c] = 1 if a > registers[b] else 0
117+
elif opcode == "gtri":
118+
registers[c] = 1 if registers[a] > b else 0
119+
elif opcode == "gtrr":
120+
registers[c] = 1 if registers[a] > registers[b] else 0
121+
122+
elif opcode == "eqir":
123+
registers[c] = 1 if a == registers[b] else 0
124+
elif opcode == "eqri":
125+
registers[c] = 1 if registers[a] == b else 0
126+
elif opcode == "eqrr":
127+
registers[c] = 1 if registers[a] == registers[b] else 0
128+
129+
if registers == final:
130+
opcodes_mapping[numeric_opcode].append(opcode)
131+
matching_opcodes.append(opcode)
132+
133+
if len(matching_opcodes) >= 3:
134+
more_than_3_opcodes += 1
135+
136+
i += 3
137+
138+
if part_to_test == 1:
139+
puzzle_actual_result = more_than_3_opcodes
140+
141+
else:
142+
opcodes_mapping = {i: set(opcodes_mapping[i]) for i in opcodes_mapping}
143+
144+
final_mapping = [0] * 16
145+
146+
while 0 in final_mapping:
147+
new_match = [i for i in opcodes_mapping if len(opcodes_mapping[i]) == 1]
148+
numeric, alpha = new_match[0], opcodes_mapping[new_match[0]].pop()
149+
150+
final_mapping[numeric] = alpha
151+
152+
for i in opcodes_mapping:
153+
if alpha in opcodes_mapping[i]:
154+
opcodes_mapping[i].remove(alpha)
155+
156+
registers = [0] * 4
157+
for operation in test_program:
158+
opcode = final_mapping[int(operation.split(" ")[0])]
159+
a, b, c = map(int, operation.split(" ")[1:])
160+
161+
print(operation, opcode, a, b, c)
162+
163+
if opcode == "addr":
164+
registers[c] = registers[a] + registers[b]
165+
elif opcode == "addi":
166+
registers[c] = registers[a] + b
167+
168+
elif opcode == "mulr":
169+
registers[c] = registers[a] * registers[b]
170+
elif opcode == "muli":
171+
registers[c] = registers[a] * b
172+
173+
elif opcode == "banr":
174+
registers[c] = registers[a] & registers[b]
175+
elif opcode == "bani":
176+
registers[c] = registers[a] & b
177+
178+
elif opcode == "borr":
179+
registers[c] = registers[a] | registers[b]
180+
elif opcode == "bori":
181+
registers[c] = registers[a] | b
182+
183+
elif opcode == "setr":
184+
registers[c] = registers[a]
185+
elif opcode == "seti":
186+
registers[c] = a
187+
188+
elif opcode == "gtir":
189+
registers[c] = 1 if a > registers[b] else 0
190+
elif opcode == "gtri":
191+
registers[c] = 1 if registers[a] > b else 0
192+
elif opcode == "gtrr":
193+
registers[c] = 1 if registers[a] > registers[b] else 0
194+
195+
elif opcode == "eqir":
196+
registers[c] = 1 if a == registers[b] else 0
197+
elif opcode == "eqri":
198+
registers[c] = 1 if registers[a] == b else 0
199+
elif opcode == "eqrr":
200+
registers[c] = 1 if registers[a] == registers[b] else 0
201+
202+
puzzle_actual_result = registers[0]
203+
204+
# -------------------------------- Outputs / results --------------------------------- #
205+
206+
print("Expected result : " + str(puzzle_expected_result))
207+
print("Actual result : " + str(puzzle_actual_result))

0 commit comments

Comments
 (0)