summaryrefslogtreecommitdiff
path: root/2024/aoc2024-d24.py
blob: 49d2c6fdf014dd54a5316fc649c83df8e5770ad3 (plain)
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
#advent of code 2024
#day 24
#part 2 requires reading the input, then either solve by hand (like I did)
#or make some kind of detection of abnormailities (for example,
#z-wires should always by outputted by XOR gate, 
#output of x XOR y should always go as input to another XOR connected to z-wire etc
#basically the whole program is just a lot of adder gates,
#adding all bits from x and y wires and outputting them into z-wires,
#mixed together with 8 errors.
#part 1 is kind of shitty so I won't bother explaining.
#I should probably implement some kind of verification of calculations
#that is: calculate the z in binary, calculate the x and y in binary
#and calculate the z as a sum of x and y

import re
data_initial, data_gates = open("24.in","r").read().split("\n\n");

Wires = {};
AllGates = {};

def calc(IN01,GATE,IN02,OUT):
	CurrentValue = Wires.get(OUT,False);
	if GATE == "AND": Wires[OUT] = Wires[IN01] & Wires[IN02];
	elif GATE == "OR": Wires[OUT] = Wires[IN01] | Wires[IN02];
	elif GATE == "XOR": Wires[OUT] = Wires[IN01] ^ Wires[IN02];

for line in data_gates.strip().split("\n"):
	in1, gt, in2, out = re.findall(r'\w+',line.strip());
	AllGates[(in1, gt, in2, out)] = False;

for line in data_initial.split("\n"):
	wire, wireval = line.strip().split(": ");
	Wires[wire] = bool(int(wireval));

go = True; #keep hgoing until all gates were used
while go:
	go = False;
	for Gate in AllGates:
		if AllGates[Gate]: continue; #skip gates which already ran 
		go = True;
		a1,a2,a3,a4 = Gate;
		if Wires.get(a1,"notyet") != "notyet" and Wires.get(a3,"notyet") != "notyet":
			  calc(*Gate);
			  AllGates[Gate] = True;

X_set = [];
Y_set = [];
Z_set = [];
for w in Wires:
	if w[0] == "x": X_set.append((w,int(Wires[w])));
	if w[0] == "y": Y_set.append((w,int(Wires[w])));
	if w[0] == "z": Z_set.append((w,int(Wires[w])));

Xvals = reversed(sorted(X_set, key = lambda m: m[0]));
Yvals = reversed(sorted(Y_set, key = lambda m: m[0]));
Z_set = reversed(sorted(Z_set, key = lambda m: m[0]));
Xbinary, Ybinary, Zbinary = "","","";
for zzz in Z_set: Zbinary += str(zzz[1]);
for yyy in Yvals: Ybinary += str(yyy[1]);
for xxx in Xvals: Xbinary += str(xxx[1]);
Zcorrect = int(Xbinary,2) + int(Ybinary,2);
Zcorrbin = str(bin(Zcorrect));
print("diagnostics");
print("binary X =   ", Xbinary);
print("binary Y =   ", Ybinary);
print(f'(addition)  {"-"*len(Zcorrbin)}');
print("binary Z =", Zcorrbin);
print();
print("decimal X =", int(Xbinary,2));
print("decimal Y =", int(Ybinary,2));
print("decimal Z =", Zcorrect, "<- this should be the output for part 2");
print("false Z   =", Zbinary);

part1 = int(Zbinary,2)
print();
print("part 1 = ", part1);
#hardcoded for my input, I did it with pen and paper
FoundIncorrectWires = ["wbw","wgb","jct","z39","gwh","z09","rcb","z21"];
FoundIncorrectWires = sorted(FoundIncorrectWires);
part2 = ",".join(FoundIncorrectWires);
print("part 2 = ", part2);