Spaces:
Running
Running
def load_data(file): | |
with open(file) as f: | |
data = f.readlines() | |
values = {} | |
for idx, line in enumerate(data): | |
if line == "\n": | |
break | |
name, value = line.split(":") | |
value = int(value) | |
values[name] = value | |
instructions = {} | |
for line in data[idx+1:]: | |
instruction, assignment = line.split("->") | |
instructions[assignment.strip("\n").strip()] = instruction.strip() | |
return values, instructions | |
def eval(v0, v1, op): | |
if op == "AND": | |
return v0 and v1 | |
elif op == "OR": | |
return v0 or v1 | |
elif op == "XOR": | |
return v0 ^ v1 | |
else: | |
raise ValueError("Unknown OP: ", op) | |
file = "input.txt" | |
values, instructions = load_data(file) | |
assignments = list(instructions.keys()) | |
# for assignment, inst in instructions.items(): | |
while len(assignments) > 0: | |
assignment = assignments.pop(0) | |
inst = instructions[assignment] | |
x0, op, x1 = inst.split() | |
v0 = values.get(x0) | |
v1 = values.get(x1) | |
if v0 is not None and v1 is not None: | |
values[assignment] = eval(v0, v1, op) | |
else: | |
assignments.append(assignment) | |
z_wires = {v: val for v, val in values.items() if v.startswith("z")} | |
z_wire_keys = sorted(z_wires.keys())[::-1] | |
bits = "" | |
for k in z_wire_keys: | |
bits += str(values[k]) | |
value = int(bits, 2) | |
print(value) | |
## Part 2 | |
# import copy | |
# | |
# def get_val(letter, values): | |
# | |
# letter_wires = {v: val for v, val in values.items() if v.startswith(letter)} | |
# letter_wire_keys = sorted(letter_wires.keys())[::-1] | |
# | |
# bits = "" | |
# for k in letter_wire_keys: | |
# bits += str(values[k]) | |
# | |
# value = int(bits, 2) | |
# | |
# return value | |
# | |
# | |
# def get_bits(letter, values): | |
# | |
# letter_wires = {v: val for v, val in values.items() if v.startswith(letter)} | |
# letter_wire_keys = sorted(letter_wires.keys())[::-1] | |
# | |
# bits = "" | |
# for k in letter_wire_keys: | |
# bits += str(values[k]) | |
# | |
# return bits | |
# | |
# def compute_instructions(values, instructions): | |
# values = values.copy() | |
# assignments = list(instructions.keys()) | |
# while len(assignments) > 0: | |
# assignment = assignments.pop(0) | |
# | |
# inst = instructions[assignment] | |
# x0, op, x1 = inst.split() | |
# | |
# | |
# v0 = values.get(x0) | |
# v1 = values.get(x1) | |
# | |
# if v0 is not None and v1 is not None: | |
# values[assignment] = eval(v0, v1, op) | |
# else: | |
# assignments.append(assignment) | |
# | |
# | |
# | |
# return values, instructions | |
# | |
# | |
# def swap_instructions(k1, k2, instructions): | |
# inst1 = instructions[k1] | |
# inst2 = instructions[k2] | |
# | |
# instructions[k1] = inst2 | |
# instructions[k2] = inst1 | |
# | |
# return instructions | |
# | |
# def swap_2_instructions(swap1, swap2, instructions): | |
# instructions = instructions.copy() | |
# | |
# for swap in [swap1, swap2]: | |
# k1, k2 = swap | |
# instructions = swap_instructions(k1, k2, instructions) | |
# | |
# return instructions | |
# | |
# | |
# # Test part 1 still works | |
# # file = "test.txt" | |
# # values, instructions = load_data(file) | |
# # new_vals, new_inst = compute_instructions(values.copy(), instructions.copy()) | |
# # z_val = get_val("z", new_vals) | |
# # print(z_val) | |
# | |
# def compute_instructions_2(values, instructions): | |
# values = values.copy() | |
# assignments = list(instructions.keys()) | |
# count = 0 | |
# while len(assignments) > 0 and count < 1000: | |
# count += 1 | |
# assignment = assignments.pop(0) | |
# | |
# inst = instructions[assignment] | |
# x0, op, x1 = inst.split() | |
# | |
# | |
# v0 = values.get(x0) | |
# v1 = values.get(x1) | |
# | |
# if v0 is not None and v1 is not None: | |
# values[assignment] = eval(v0, v1, op) | |
# else: | |
# assignments.append(assignment) | |
# | |
# return values, instructions | |
# | |
# # file = "test2.txt" | |
# file = "input.txt" | |
# values, instructions = load_data(file) | |
# | |
# x_val = get_val("x", values) | |
# y_val = get_val("y", values) | |
# | |
# x_bits = get_bits("x", values) | |
# y_bits = get_bits("y", values) | |
# | |
# | |
# swap_1 = ("z05", "z00") | |
# swap_2 = ("z01", "z02") | |
# | |
# new_inst = swap_2_instructions(swap_1, swap_2, instructions) | |
# new_vals, new_inst = compute_instructions(values.copy(), new_inst.copy()) | |
# z_val = get_val("z", new_vals) | |
# z_bits = get_bits("z", new_vals) | |
# | |
# if x_val + y_val == z_val: | |
# print("Good!") | |
# | |
# | |
# def mega_brute_force_of_life(): | |
# k = list(instructions.keys()) | |
# | |
# for i in range(len(k)): | |
# for j in range(i+1, len(k)): | |
# swap_1 = (k[i], k[j]) | |
# | |
# k_remain = k.copy() | |
# k_remain.remove(k[i]) | |
# k_remain.remove(k[j]) | |
# | |
# for ii in range(len(k_remain)): | |
# for jj in range(ii+1, len(k_remain)): | |
# print(jj) | |
# swap_2 = (k_remain[ii], k_remain[jj]) | |
# | |
# print(swap_1) | |
# print(swap_2) | |
# | |
# new_inst = swap_2_instructions(swap_1, swap_2, instructions) | |
# new_vals, new_inst = compute_instructions_2(values.copy(), new_inst.copy()) | |
# | |
# z_val = get_val("z", new_vals) | |
# z_bits = get_bits("z", new_vals) | |
# | |
# if x_val + y_val == z_val: | |
# print("Good!") | |
# return swap_1, swap_2 | |
# | |
# # swap_1, swap_2 = mega_brute_force_of_life() | |