commit 4cbf560227e654b136509f7732239dcded631c3e
parent 3f8c80cc32bc25d5c29ebc72161d691787677ef1
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date: Wed, 25 Dec 2024 00:40:50 +0100
Day 24 2024 still don't know how I managed to solve this
Diffstat:
11 files changed, 1090 insertions(+), 0 deletions(-)
diff --git a/2024/24/Makefile b/2024/24/Makefile
@@ -0,0 +1,11 @@
+CC=g++ -std=c++20 -g -Wall
+
+a:
+ ${CC} -o a.out day24a.cpp
+ ./a.out
+
+b:
+ ${CC} -o b.out day24b.cpp
+ ./b.out
+
+.PHONY: a b
diff --git a/2024/24/clean.sh b/2024/24/clean.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+sed 's/XOR/^/; s/OR/|/; s/AND/\&/'
diff --git a/2024/24/day24a.cpp b/2024/24/day24a.cpp
@@ -0,0 +1,88 @@
+/* Use clean.sh on the input first */
+
+#include <algorithm>
+#include <cstdint>
+#include <iostream>
+#include <map>
+#include <queue>
+#include <ranges>
+#include <set>
+#include <sstream>
+#include <string>
+#include <string_view>
+#include <vector>
+using namespace std;
+
+int8_t state[36*36*36];
+
+int d(char x) { return x >= 'a' && x <= 'z' ? x-'a' : 26+x-'0'; }
+int index(char a, char b, char c) { return d(c) + 36 * (d(b) + 36 * d(a)); }
+int z(int i) { return index('z', (i/10)+'0', (i%10)+'0'); }
+
+enum class Op { AND, OR, XOR };
+
+class Gate {
+public:
+ int x, y, z;
+ Op op;
+
+ bool ready() const {
+ return state[x] != -1 && state[y] != -1;
+ }
+
+ bool operate() const { /* Returns true if the operation flips a bit */
+ auto oldstate = state[z];
+ switch (op) {
+ case Op::AND:
+ state[z] = state[x] & state[y];
+ break;
+ case Op::OR:
+ state[z] = state[x] | state[y];
+ break;
+ case Op::XOR:
+ state[z] = state[x] ^ state[y];
+ break;
+ }
+ return oldstate != state[z];
+ }
+};
+
+Op make_op(char c) {
+ switch (c) {
+ case '&': return Op::AND;
+ case '|': return Op::OR;
+ default: return Op::XOR;
+ }
+}
+
+int main() {
+ vector<Gate> gates;
+ fill(state, state + 36*36*36, -1);
+ string line;
+
+ while (getline(cin, line) && line != "")
+ state[index(line[0], line[1], line[2])] = line[5]-'0';
+
+ while (getline(cin, line))
+ gates.push_back(Gate {
+ .x = index(line[0], line[1], line[2]),
+ .y = index(line[6], line[7], line[8]),
+ .z = index(line[13], line[14], line[15]),
+ .op = make_op(line[4])
+ });
+
+ for (bool flag = true; flag; ) {
+ flag = false;
+ for (auto g : gates)
+ if (g.ready())
+ flag = flag || g.operate();
+ }
+
+ int64_t result = 0;
+ for (int64_t i = 0, j = 1; state[z(i)] != -1; i++, j *= 2)
+ result += (int64_t)state[z(i)] * j;
+
+ cout << result << endl;
+
+ return 0;
+}
diff --git a/2024/24/day24b.cpp b/2024/24/day24b.cpp
@@ -0,0 +1,247 @@
+/*
+
+I don't know what addition circuits look like, but they should have some
+kind of regular structure. I manually inspected how the first few digits
+behave to get an idea.
+
+With some more manual inspection I noticed that the "temporary result"
+gates that are results of a XOR operation always appear as terms in
+exactly one XOR and one AND operation; the same thing happens for
+OR-results, while AND-results appear as terms only in one OR operation.
+
+This excludes z-gates, which are the result of a XOR operation (except
+for z45, which is the result of an OR operation) and do not appear as
+terms in any other operation. And of course "errors" do not follow this
+pattern either.
+
+So what I do is going through all gates and see if their result
+satisfies the conditions above. This gives 8 candidates for the error,
+but unfortunately they were not the correct answer (I tried submitting
+this list 3 times).
+
+I thought about it a bit longer and I realized that one of the entries
+in my list is rfg, which appears as the result of x00 & y00. I thought
+that since this was the first digit, it could be an edge case and thus
+correctly behaving differently from the others. This leaves me with
+7 candidates only, so I have to find another one.
+
+One of the gates I had to swap (z23) was the result of an OR operation,
+but should have been the result o a XOR. But any XOR-result could be
+swapped with an OR-result without breaking the conditions I guessed at the
+beginning. So I tried them all: for every XOR-gate I swapped the results
+with my other 7 candidates in every way possible according to my rules,
+and checked which of these re-arrangements gave the correct answer for
+the example input.
+
+I found two candidates (kdf and nsr). I could have checked more inputs
+to see which of the two worked, or I could just try both of them. Of
+course, I choose the second option, and kdf worked.
+
+Did I get the gold star? Yes. Do I know how I was supposed to solve this
+problem? Not a clue. But hey, I solved it without hints, a win is a win.
+
+*/
+
+#include <algorithm>
+#include <cstdint>
+#include <iostream>
+#include <map>
+#include <queue>
+#include <ranges>
+#include <set>
+#include <sstream>
+#include <string>
+#include <string_view>
+#include <vector>
+using namespace std;
+
+enum class Op { AND, OR, XOR };
+
+class Gate {
+public:
+ int x, y, z;
+ Op op;
+
+ bool ready(const int8_t *state) const {
+ return state[x] != -1 && state[y] != -1;
+ }
+
+ bool operate(int8_t *state) const { /* Returns true if the operation flips a bit */
+ auto oldstate = state[z];
+ switch (op) {
+ case Op::AND:
+ state[z] = state[x] & state[y];
+ break;
+ case Op::OR:
+ state[z] = state[x] | state[y];
+ break;
+ case Op::XOR:
+ state[z] = state[x] ^ state[y];
+ break;
+ }
+ return oldstate != state[z];
+ }
+};
+
+int8_t state[36*36*36];
+vector<Gate> gates;
+
+int d(char x) { return x >= 'a' && x <= 'z' ? x-'a' : 26+x-'0'; }
+char h(int i) { return i >= 26 ? i-26+'0' : i+'a'; }
+int index(char a, char b, char c) { return d(c) + 36 * (d(b) + 36 * d(a)); }
+string name(int i) {
+ string r = " ";
+ r[0] = h(i / (36*36));
+ r[1] = h((i/ 36) % 36);
+ r[2] = h(i % 36);
+ return r;
+}
+
+int64_t digit(int i, char c) {
+ return index(c, (i/10)+'0', (i%10)+'0');
+}
+
+int64_t getnum(char c, int m) {
+ int64_t result = 0;
+ for (int64_t i = 0, j = 1; i < m; i++, j *= 2)
+ result += (int64_t)state[digit(i, c)] * j;
+ return result;
+}
+
+Op make_op(char c) {
+ switch (c) {
+ case '&': return Op::AND;
+ case '|': return Op::OR;
+ default: return Op::XOR;
+ }
+}
+
+char opname(Op op) {
+ switch (op) {
+ case Op::AND: return '&';
+ case Op::OR: return '|';
+ default: return '^';
+ }
+}
+
+void printop(Gate g, const vector<Op>& a) {
+ cout << name(g.z) << " is " << name(g.x) << " " << opname(g.op)
+ << " " << name(g.y) << " but appears in ";
+ for (auto op : a)
+ cout << opname(op) << " ";
+ cout << endl;
+}
+
+int gg(const string& rr) {
+ for (unsigned i = 0; i < gates.size(); i++)
+ if (name(gates[i].z) == rr)
+ return i;
+ return -1;
+}
+
+void swapgates(vector<Gate>& local_gates, vector<int> ixsa,
+ vector<int> iasx, int iosx, int gswap) {
+}
+
+void run(int8_t *state, const vector<Gate>& gates) {
+ for (bool flag = true; flag; ) {
+ flag = false;
+ for (auto g : gates)
+ if (g.ready(state))
+ flag = flag || g.operate(state);
+ }
+ int64_t x = getnum('x', 45);
+ int64_t y = getnum('y', 45);
+ int64_t z = getnum('z', 46);
+ if (x+y == z) cout << "Correct result! " << z << endl;
+}
+
+int main() {
+ fill(state, state + 36*36*36, -1);
+ string line;
+
+ while (getline(cin, line) && line != "")
+ state[index(line[0], line[1], line[2])] = line[5]-'0';
+
+ while (getline(cin, line))
+ gates.push_back(Gate {
+ .x = index(line[0], line[1], line[2]),
+ .y = index(line[6], line[7], line[8]),
+ .z = index(line[13], line[14], line[15]),
+ .op = make_op(line[4])
+ });
+
+#if 0
+ /* Print error candidates */
+ vector<string> bad;
+ for (auto g : gates) {
+ if (name(g.z)[0] == 'z') {
+ if ((name(g.z) == "z45" && g.op != Op::OR) ||
+ (name(g.z) != "z45" && g.op != Op::XOR)) {
+ printop(g, vector<Op>());
+ bad.push_back(name(g.z));
+ }
+ continue;
+ }
+ vector<Op> appears_in;
+ for (auto f : gates)
+ if (g.z == f.x || g.z == f.y)
+ appears_in.push_back(f.op);
+ if (g.op == Op::AND) {
+ if (appears_in.size() != 1 || appears_in[0] != Op::OR) {
+ printop(g, appears_in);
+ bad.push_back(name(g.z));
+ }
+ } else {
+ if (appears_in.size() != 2 ||
+ find(appears_in.begin(), appears_in.end(), Op::AND) == appears_in.end() ||
+ find(appears_in.begin(), appears_in.end(), Op::XOR) == appears_in.end()) {
+ printop(g, appears_in);
+ bad.push_back(name(g.z));
+ }
+ }
+ }
+
+ sort(bad.begin(), bad.end());
+
+ for (auto b : bad)
+ cout << b << ",";
+ cout << endl;
+#endif
+
+ vector<string> is_xor_shouldbe_and = { "ckj", "rpp", "dbp" };
+ vector<string> is_and_shouldbe_xor = { "fdv", "z15", "z39" };
+ string is_or_shouldbe_xor = "z23";
+
+ vector<int> ixsa = { gg("ckj"), gg("rpp"), gg("dbp") };
+ vector<int> iasx = { gg("fdv"), gg("z15"), gg("z39") };
+ int iosx = gg("z23");
+
+ vector<vector<pair<int, int>>> swaps = {
+ {{ixsa[0],iasx[0]}, {ixsa[1],iasx[1]}, {ixsa[2],iasx[2]}},
+ {{ixsa[0],iasx[0]}, {ixsa[1],iasx[2]}, {ixsa[2],iasx[1]}},
+ {{ixsa[0],iasx[1]}, {ixsa[1],iasx[0]}, {ixsa[2],iasx[2]}},
+ {{ixsa[0],iasx[1]}, {ixsa[1],iasx[2]}, {ixsa[2],iasx[0]}},
+ {{ixsa[0],iasx[2]}, {ixsa[1],iasx[1]}, {ixsa[2],iasx[0]}},
+ {{ixsa[0],iasx[2]}, {ixsa[1],iasx[0]}, {ixsa[2],iasx[1]}}
+ };
+
+ for (unsigned gswap = 0; gswap < gates.size(); gswap++) {
+ if (find(ixsa.begin(), ixsa.end(), gswap) != ixsa.end() ||
+ find(iasx.begin(), iasx.end(), gswap) != iasx.end() ||
+ (int)gswap == iosx || gates[gswap].op != Op::XOR)
+ continue;
+ cout << "Trying gswap " << name(gates[gswap].z) << endl;
+ for (auto ss : swaps) {
+ auto local_state = state;
+ auto local_gates = gates;
+ swap(local_gates[ss[0].first].z, local_gates[ss[0].second].z);
+ swap(local_gates[ss[1].first].z, local_gates[ss[1].second].z);
+ swap(local_gates[ss[2].first].z, local_gates[ss[2].second].z);
+ swap(local_gates[iosx].z, local_gates[gswap].z);
+ run(local_state, local_gates);
+ }
+ }
+
+ return 0;
+}
diff --git a/2024/24/input b/2024/24/input
@@ -0,0 +1,313 @@
+x00: 1
+x01: 0
+x02: 1
+x03: 1
+x04: 0
+x05: 0
+x06: 1
+x07: 1
+x08: 0
+x09: 1
+x10: 1
+x11: 1
+x12: 1
+x13: 0
+x14: 1
+x15: 1
+x16: 0
+x17: 1
+x18: 1
+x19: 1
+x20: 0
+x21: 0
+x22: 0
+x23: 1
+x24: 1
+x25: 0
+x26: 1
+x27: 0
+x28: 0
+x29: 0
+x30: 0
+x31: 1
+x32: 1
+x33: 0
+x34: 1
+x35: 0
+x36: 1
+x37: 1
+x38: 0
+x39: 0
+x40: 0
+x41: 0
+x42: 1
+x43: 1
+x44: 1
+y00: 1
+y01: 0
+y02: 0
+y03: 1
+y04: 1
+y05: 0
+y06: 0
+y07: 0
+y08: 0
+y09: 0
+y10: 0
+y11: 1
+y12: 0
+y13: 1
+y14: 0
+y15: 1
+y16: 0
+y17: 1
+y18: 0
+y19: 1
+y20: 1
+y21: 0
+y22: 1
+y23: 1
+y24: 0
+y25: 0
+y26: 0
+y27: 0
+y28: 0
+y29: 1
+y30: 0
+y31: 0
+y32: 1
+y33: 0
+y34: 1
+y35: 0
+y36: 1
+y37: 1
+y38: 0
+y39: 1
+y40: 1
+y41: 1
+y42: 1
+y43: 0
+y44: 1
+
+mjw AND bvt -> bjv
+y41 XOR x41 -> fkk
+tgm AND qtf -> pkr
+gcg XOR mwj -> z11
+pth AND djn -> mtn
+qbw XOR fqf -> ckj
+tjr OR hgs -> fkb
+y10 XOR x10 -> mtg
+ths XOR kwr -> z14
+x18 XOR y18 -> fgn
+kwr AND ths -> qqp
+jpj OR ggk -> vpn
+pnd XOR sbb -> z09
+x32 XOR y32 -> bvs
+twn XOR njm -> z07
+y18 AND x18 -> tpt
+gvm XOR fkk -> z41
+pjs AND vvd -> cfn
+x00 AND y00 -> rfg
+y14 AND x14 -> prf
+y14 XOR x14 -> ths
+ppf OR jmf -> dpb
+x35 AND y35 -> dsc
+svn AND vsb -> fmg
+y38 AND x38 -> ngh
+x44 AND y44 -> tmh
+vvd XOR pjs -> z08
+x37 XOR y37 -> bkk
+y19 XOR x19 -> pwn
+fmg OR rcq -> hth
+vft XOR vbn -> z38
+x42 XOR y42 -> jdh
+nhj OR nwq -> kwr
+ddt XOR rjd -> z25
+vpn AND mtg -> pbg
+x42 AND y42 -> jsf
+smr XOR bkt -> z20
+y27 XOR x27 -> dfh
+chk AND pjd -> dqb
+wcn OR sqk -> smr
+jdk OR rpp -> mjw
+x43 XOR y43 -> djn
+y23 AND x23 -> rdt
+x16 AND y16 -> wfs
+jfb OR jsf -> pth
+ksc AND jbs -> dkd
+y29 XOR x29 -> mfw
+sjs XOR qcq -> z44
+y33 XOR x33 -> wsk
+jbs XOR ksc -> z21
+y17 XOR x17 -> qdh
+kbs AND pwn -> sqk
+y41 AND x41 -> tjr
+ffp OR shb -> vbn
+x40 XOR y40 -> bvt
+y05 XOR x05 -> wgk
+fcm AND swg -> nwq
+y39 XOR x39 -> vqr
+sqp OR mbd -> phr
+pkt OR ckj -> sjd
+fps AND rfg -> fdn
+x07 AND y07 -> rnh
+nsr XOR gsd -> kdf
+x16 XOR y16 -> ftv
+sjd AND ftv -> rgk
+x37 AND y37 -> ffp
+vpn XOR mtg -> z10
+vbt AND vqr -> z39
+x43 AND y43 -> vcd
+hnr AND kdf -> htp
+x26 AND y26 -> tpw
+dqb OR dhv -> gsd
+wbp AND vbw -> vnj
+y26 XOR x26 -> tpb
+fgn AND phr -> mqr
+y06 AND x06 -> fdv
+vgc OR vpq -> ksc
+mjw XOR bvt -> z40
+rhm OR dkd -> chk
+y24 XOR x24 -> hnr
+dvh OR dnq -> fkt
+cdk OR gsq -> kvm
+x15 XOR y15 -> fqf
+y40 AND x40 -> mbk
+qfg OR vwc -> vbw
+mtq XOR kvm -> z12
+vbn AND vft -> rfr
+hth AND mfw -> qfg
+fkk AND gvm -> hgs
+vjf AND fdv -> wdv
+gcg AND mwj -> gsq
+y29 AND x29 -> vwc
+wbp XOR vbw -> z30
+jvq OR htp -> ddt
+y24 AND x24 -> jvq
+kgf AND ftq -> wmv
+x35 XOR y35 -> rfc
+fdn OR hnq -> mvw
+y11 XOR x11 -> gcg
+x25 AND y25 -> dnq
+y12 XOR x12 -> mtq
+y44 XOR x44 -> qcq
+dsc OR prv -> ftq
+wsk AND vms -> bpw
+rsj XOR bkk -> z37
+djn XOR pth -> z43
+wdv OR dbp -> njm
+rgn OR rnh -> pjs
+vqr XOR vbt -> rpp
+y34 XOR x34 -> wpp
+y13 AND x13 -> nhj
+rnt AND rfc -> prv
+dpb XOR wgk -> z05
+jwh OR tmh -> z45
+nfs XOR mvw -> z02
+dfh AND fvr -> qnd
+x15 AND y15 -> z15
+x20 XOR y20 -> bkt
+vcd OR mtn -> sjs
+y04 XOR x04 -> rqm
+mfw XOR hth -> z29
+qbw AND fqf -> pkt
+y34 AND x34 -> cgd
+pjd XOR chk -> z22
+y01 XOR x01 -> fps
+y08 AND x08 -> ndk
+btn OR cgd -> rnt
+mvw AND nfs -> jqp
+pgm AND rqm -> jmf
+dfh XOR fvr -> z27
+kbf AND qdh -> sqp
+pwn XOR kbs -> z19
+x02 XOR y02 -> nfs
+rth OR wmv -> rsj
+jqp OR hvw -> tgm
+fps XOR rfg -> z01
+y19 AND x19 -> wcn
+x10 AND y10 -> wkd
+x00 XOR y00 -> z00
+kqm AND dmp -> vnn
+hnr XOR kdf -> z24
+x01 AND y01 -> hnq
+x22 AND y22 -> dhv
+y36 XOR x36 -> kgf
+y27 AND x27 -> dcr
+x09 AND y09 -> ggk
+y23 XOR x23 -> nsr
+ktr OR bpw -> fdr
+x21 AND y21 -> rhm
+dcf OR pkr -> pgm
+x09 XOR y09 -> pnd
+x06 XOR y06 -> dbp
+frt OR jwp -> vjf
+x03 XOR y03 -> qtf
+x08 XOR y08 -> vvd
+x02 AND y02 -> hvw
+y21 XOR x21 -> jbs
+kqm XOR dmp -> z31
+npq OR ckn -> vms
+pnd AND sbb -> jpj
+phr XOR fgn -> z18
+sjd XOR ftv -> z16
+wkd OR pbg -> mwj
+wpp AND fdr -> btn
+bkt AND smr -> vgc
+x30 AND y30 -> tvj
+x28 XOR y28 -> svn
+vms XOR wsk -> z33
+swg XOR fcm -> z13
+prf OR qqp -> qbw
+rgk OR wfs -> kbf
+nsr AND gsd -> rqt
+x28 AND y28 -> rcq
+x20 AND y20 -> vpq
+dbw OR tpw -> fvr
+rnt XOR rfc -> z35
+x36 AND y36 -> rth
+vnn OR jwg -> jth
+sjs AND qcq -> jwh
+x07 XOR y07 -> twn
+dpb AND wgk -> jwp
+rqt OR rdt -> z23
+gnr OR qtv -> swg
+rqm XOR pgm -> z04
+x12 AND y12 -> gnr
+njm AND twn -> rgn
+rsj AND bkk -> shb
+x32 AND y32 -> ckn
+qdh XOR kbf -> z17
+x05 AND y05 -> frt
+vsb XOR svn -> z28
+x38 XOR y38 -> vft
+y11 AND x11 -> cdk
+fkb AND jdh -> jfb
+x31 XOR y31 -> kqm
+y13 XOR x13 -> fcm
+cfn OR ndk -> sbb
+x04 AND y04 -> ppf
+x31 AND y31 -> jwg
+fkt XOR tpb -> z26
+jth AND bvs -> npq
+kgf XOR ftq -> z36
+x25 XOR y25 -> rjd
+bvs XOR jth -> z32
+fkt AND tpb -> dbw
+bjv OR mbk -> gvm
+jdh XOR fkb -> z42
+y39 AND x39 -> jdk
+x03 AND y03 -> dcf
+y22 XOR x22 -> pjd
+mqr OR tpt -> kbs
+kvm AND mtq -> qtv
+rjd AND ddt -> dvh
+fdr XOR wpp -> z34
+y17 AND x17 -> mbd
+y33 AND x33 -> ktr
+qnd OR dcr -> vsb
+fdv XOR vjf -> z06
+ngh OR rfr -> vbt
+tgm XOR qtf -> z03
+y30 XOR x30 -> wbp
+tvj OR vnj -> dmp
diff --git a/2024/24/input-clean b/2024/24/input-clean
@@ -0,0 +1,313 @@
+x00: 1
+x01: 0
+x02: 1
+x03: 1
+x04: 0
+x05: 0
+x06: 1
+x07: 1
+x08: 0
+x09: 1
+x10: 1
+x11: 1
+x12: 1
+x13: 0
+x14: 1
+x15: 1
+x16: 0
+x17: 1
+x18: 1
+x19: 1
+x20: 0
+x21: 0
+x22: 0
+x23: 1
+x24: 1
+x25: 0
+x26: 1
+x27: 0
+x28: 0
+x29: 0
+x30: 0
+x31: 1
+x32: 1
+x33: 0
+x34: 1
+x35: 0
+x36: 1
+x37: 1
+x38: 0
+x39: 0
+x40: 0
+x41: 0
+x42: 1
+x43: 1
+x44: 1
+y00: 1
+y01: 0
+y02: 0
+y03: 1
+y04: 1
+y05: 0
+y06: 0
+y07: 0
+y08: 0
+y09: 0
+y10: 0
+y11: 1
+y12: 0
+y13: 1
+y14: 0
+y15: 1
+y16: 0
+y17: 1
+y18: 0
+y19: 1
+y20: 1
+y21: 0
+y22: 1
+y23: 1
+y24: 0
+y25: 0
+y26: 0
+y27: 0
+y28: 0
+y29: 1
+y30: 0
+y31: 0
+y32: 1
+y33: 0
+y34: 1
+y35: 0
+y36: 1
+y37: 1
+y38: 0
+y39: 1
+y40: 1
+y41: 1
+y42: 1
+y43: 0
+y44: 1
+
+mjw & bvt -> bjv
+y41 ^ x41 -> fkk
+tgm & qtf -> pkr
+gcg ^ mwj -> z11
+pth & djn -> mtn
+qbw ^ fqf -> ckj
+tjr | hgs -> fkb
+y10 ^ x10 -> mtg
+ths ^ kwr -> z14
+x18 ^ y18 -> fgn
+kwr & ths -> qqp
+jpj | ggk -> vpn
+pnd ^ sbb -> z09
+x32 ^ y32 -> bvs
+twn ^ njm -> z07
+y18 & x18 -> tpt
+gvm ^ fkk -> z41
+pjs & vvd -> cfn
+x00 & y00 -> rfg
+y14 & x14 -> prf
+y14 ^ x14 -> ths
+ppf | jmf -> dpb
+x35 & y35 -> dsc
+svn & vsb -> fmg
+y38 & x38 -> ngh
+x44 & y44 -> tmh
+vvd ^ pjs -> z08
+x37 ^ y37 -> bkk
+y19 ^ x19 -> pwn
+fmg | rcq -> hth
+vft ^ vbn -> z38
+x42 ^ y42 -> jdh
+nhj | nwq -> kwr
+ddt ^ rjd -> z25
+vpn & mtg -> pbg
+x42 & y42 -> jsf
+smr ^ bkt -> z20
+y27 ^ x27 -> dfh
+chk & pjd -> dqb
+wcn | sqk -> smr
+jdk | rpp -> mjw
+x43 ^ y43 -> djn
+y23 & x23 -> rdt
+x16 & y16 -> wfs
+jfb | jsf -> pth
+ksc & jbs -> dkd
+y29 ^ x29 -> mfw
+sjs ^ qcq -> z44
+y33 ^ x33 -> wsk
+jbs ^ ksc -> z21
+y17 ^ x17 -> qdh
+kbs & pwn -> sqk
+y41 & x41 -> tjr
+ffp | shb -> vbn
+x40 ^ y40 -> bvt
+y05 ^ x05 -> wgk
+fcm & swg -> nwq
+y39 ^ x39 -> vqr
+sqp | mbd -> phr
+pkt | ckj -> sjd
+fps & rfg -> fdn
+x07 & y07 -> rnh
+nsr ^ gsd -> kdf
+x16 ^ y16 -> ftv
+sjd & ftv -> rgk
+x37 & y37 -> ffp
+vpn ^ mtg -> z10
+vbt & vqr -> z39
+x43 & y43 -> vcd
+hnr & kdf -> htp
+x26 & y26 -> tpw
+dqb | dhv -> gsd
+wbp & vbw -> vnj
+y26 ^ x26 -> tpb
+fgn & phr -> mqr
+y06 & x06 -> fdv
+vgc | vpq -> ksc
+mjw ^ bvt -> z40
+rhm | dkd -> chk
+y24 ^ x24 -> hnr
+dvh | dnq -> fkt
+cdk | gsq -> kvm
+x15 ^ y15 -> fqf
+y40 & x40 -> mbk
+qfg | vwc -> vbw
+mtq ^ kvm -> z12
+vbn & vft -> rfr
+hth & mfw -> qfg
+fkk & gvm -> hgs
+vjf & fdv -> wdv
+gcg & mwj -> gsq
+y29 & x29 -> vwc
+wbp ^ vbw -> z30
+jvq | htp -> ddt
+y24 & x24 -> jvq
+kgf & ftq -> wmv
+x35 ^ y35 -> rfc
+fdn | hnq -> mvw
+y11 ^ x11 -> gcg
+x25 & y25 -> dnq
+y12 ^ x12 -> mtq
+y44 ^ x44 -> qcq
+dsc | prv -> ftq
+wsk & vms -> bpw
+rsj ^ bkk -> z37
+djn ^ pth -> z43
+wdv | dbp -> njm
+rgn | rnh -> pjs
+vqr ^ vbt -> rpp
+y34 ^ x34 -> wpp
+y13 & x13 -> nhj
+rnt & rfc -> prv
+dpb ^ wgk -> z05
+jwh | tmh -> z45
+nfs ^ mvw -> z02
+dfh & fvr -> qnd
+x15 & y15 -> z15
+x20 ^ y20 -> bkt
+vcd | mtn -> sjs
+y04 ^ x04 -> rqm
+mfw ^ hth -> z29
+qbw & fqf -> pkt
+y34 & x34 -> cgd
+pjd ^ chk -> z22
+y01 ^ x01 -> fps
+y08 & x08 -> ndk
+btn | cgd -> rnt
+mvw & nfs -> jqp
+pgm & rqm -> jmf
+dfh ^ fvr -> z27
+kbf & qdh -> sqp
+pwn ^ kbs -> z19
+x02 ^ y02 -> nfs
+rth | wmv -> rsj
+jqp | hvw -> tgm
+fps ^ rfg -> z01
+y19 & x19 -> wcn
+x10 & y10 -> wkd
+x00 ^ y00 -> z00
+kqm & dmp -> vnn
+hnr ^ kdf -> z24
+x01 & y01 -> hnq
+x22 & y22 -> dhv
+y36 ^ x36 -> kgf
+y27 & x27 -> dcr
+x09 & y09 -> ggk
+y23 ^ x23 -> nsr
+ktr | bpw -> fdr
+x21 & y21 -> rhm
+dcf | pkr -> pgm
+x09 ^ y09 -> pnd
+x06 ^ y06 -> dbp
+frt | jwp -> vjf
+x03 ^ y03 -> qtf
+x08 ^ y08 -> vvd
+x02 & y02 -> hvw
+y21 ^ x21 -> jbs
+kqm ^ dmp -> z31
+npq | ckn -> vms
+pnd & sbb -> jpj
+phr ^ fgn -> z18
+sjd ^ ftv -> z16
+wkd | pbg -> mwj
+wpp & fdr -> btn
+bkt & smr -> vgc
+x30 & y30 -> tvj
+x28 ^ y28 -> svn
+vms ^ wsk -> z33
+swg ^ fcm -> z13
+prf | qqp -> qbw
+rgk | wfs -> kbf
+nsr & gsd -> rqt
+x28 & y28 -> rcq
+x20 & y20 -> vpq
+dbw | tpw -> fvr
+rnt ^ rfc -> z35
+x36 & y36 -> rth
+vnn | jwg -> jth
+sjs & qcq -> jwh
+x07 ^ y07 -> twn
+dpb & wgk -> jwp
+rqt | rdt -> z23
+gnr | qtv -> swg
+rqm ^ pgm -> z04
+x12 & y12 -> gnr
+njm & twn -> rgn
+rsj & bkk -> shb
+x32 & y32 -> ckn
+qdh ^ kbf -> z17
+x05 & y05 -> frt
+vsb ^ svn -> z28
+x38 ^ y38 -> vft
+y11 & x11 -> cdk
+fkb & jdh -> jfb
+x31 ^ y31 -> kqm
+y13 ^ x13 -> fcm
+cfn | ndk -> sbb
+x04 & y04 -> ppf
+x31 & y31 -> jwg
+fkt ^ tpb -> z26
+jth & bvs -> npq
+kgf ^ ftq -> z36
+x25 ^ y25 -> rjd
+bvs ^ jth -> z32
+fkt & tpb -> dbw
+bjv | mbk -> gvm
+jdh ^ fkb -> z42
+y39 & x39 -> jdk
+x03 & y03 -> dcf
+y22 ^ x22 -> pjd
+mqr | tpt -> kbs
+kvm & mtq -> qtv
+rjd & ddt -> dvh
+fdr ^ wpp -> z34
+y17 & x17 -> mbd
+y33 & x33 -> ktr
+qnd | dcr -> vsb
+fdv ^ vjf -> z06
+ngh | rfr -> vbt
+tgm ^ qtf -> z03
+y30 ^ x30 -> wbp
+tvj | vnj -> dmp
diff --git a/2024/24/test1 b/2024/24/test1
@@ -0,0 +1,10 @@
+x00: 1
+x01: 1
+x02: 1
+y00: 0
+y01: 1
+y02: 0
+
+x00 AND y00 -> z00
+x01 XOR y01 -> z01
+x02 OR y02 -> z02
diff --git a/2024/24/test1-clean b/2024/24/test1-clean
@@ -0,0 +1,10 @@
+x00: 1
+x01: 1
+x02: 1
+y00: 0
+y01: 1
+y02: 0
+
+x00 & y00 -> z00
+x01 ^ y01 -> z01
+x02 | y02 -> z02
diff --git a/2024/24/test2 b/2024/24/test2
@@ -0,0 +1,47 @@
+x00: 1
+x01: 0
+x02: 1
+x03: 1
+x04: 0
+y00: 1
+y01: 1
+y02: 1
+y03: 1
+y04: 1
+
+ntg XOR fgs -> mjb
+y02 OR x01 -> tnw
+kwq OR kpj -> z05
+x00 OR x03 -> fst
+tgd XOR rvg -> z01
+vdt OR tnw -> bfw
+bfw AND frj -> z10
+ffh OR nrd -> bqk
+y00 AND y03 -> djm
+y03 OR y00 -> psh
+bqk OR frj -> z08
+tnw OR fst -> frj
+gnj AND tgd -> z11
+bfw XOR mjb -> z00
+x03 OR x00 -> vdt
+gnj AND wpb -> z02
+x04 AND y00 -> kjc
+djm OR pbm -> qhw
+nrd AND vdt -> hwm
+kjc AND fst -> rvg
+y04 OR y02 -> fgs
+y01 AND x02 -> pbm
+ntg OR kjc -> kwq
+psh XOR fgs -> tgd
+qhw XOR tgd -> z09
+pbm OR djm -> kpj
+x03 XOR y03 -> ffh
+x00 XOR y04 -> ntg
+bfw OR bqk -> z06
+nrd XOR fgs -> wpb
+frj XOR qhw -> z04
+bqk OR frj -> z07
+y03 OR x01 -> nrd
+hwm AND bqk -> z03
+tgd XOR rvg -> z12
+tnw OR pbm -> gnj
diff --git a/2024/24/test2-clean b/2024/24/test2-clean
@@ -0,0 +1,47 @@
+x00: 1
+x01: 0
+x02: 1
+x03: 1
+x04: 0
+y00: 1
+y01: 1
+y02: 1
+y03: 1
+y04: 1
+
+ntg ^ fgs -> mjb
+y02 | x01 -> tnw
+kwq | kpj -> z05
+x00 | x03 -> fst
+tgd ^ rvg -> z01
+vdt | tnw -> bfw
+bfw & frj -> z10
+ffh | nrd -> bqk
+y00 & y03 -> djm
+y03 | y00 -> psh
+bqk | frj -> z08
+tnw | fst -> frj
+gnj & tgd -> z11
+bfw ^ mjb -> z00
+x03 | x00 -> vdt
+gnj & wpb -> z02
+x04 & y00 -> kjc
+djm | pbm -> qhw
+nrd & vdt -> hwm
+kjc & fst -> rvg
+y04 | y02 -> fgs
+y01 & x02 -> pbm
+ntg | kjc -> kwq
+psh ^ fgs -> tgd
+qhw ^ tgd -> z09
+pbm | djm -> kpj
+x03 ^ y03 -> ffh
+x00 ^ y04 -> ntg
+bfw | bqk -> z06
+nrd ^ fgs -> wpb
+frj ^ qhw -> z04
+bqk | frj -> z07
+y03 | x01 -> nrd
+hwm & bqk -> z03
+tgd ^ rvg -> z12
+tnw | pbm -> gnj
diff --git a/2024/learned.txt b/2024/learned.txt
@@ -11,3 +11,4 @@ List of things I learned (or refreshed) with this year's AoC.
* Day 11: if(init; cond)
* Day 19: more practice with std::string_view for constant string
* Day 22: std::views::values for map (and keys)
+* Day 24: std::fill