diff options
Diffstat (limited to '2024/aoc2024-d24.py')
-rw-r--r-- | 2024/aoc2024-d24.py | 82 |
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); + |