summaryrefslogtreecommitdiff
path: root/2024/aoc2024-d24.py
diff options
context:
space:
mode:
Diffstat (limited to '2024/aoc2024-d24.py')
-rw-r--r--2024/aoc2024-d24.py82
1 files changed, 82 insertions, 0 deletions
diff --git a/2024/aoc2024-d24.py b/2024/aoc2024-d24.py
new file mode 100644
index 0000000..49d2c6f
--- /dev/null
+++ b/2024/aoc2024-d24.py
@@ -0,0 +1,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);
+