day24a.cpp (1785B)
1 /* Use clean.sh on the input first */ 2 3 #include <algorithm> 4 #include <cstdint> 5 #include <iostream> 6 #include <map> 7 #include <queue> 8 #include <ranges> 9 #include <set> 10 #include <sstream> 11 #include <string> 12 #include <string_view> 13 #include <vector> 14 using namespace std; 15 16 int8_t state[36*36*36]; 17 18 int d(char x) { return x >= 'a' && x <= 'z' ? x-'a' : 26+x-'0'; } 19 int index(char a, char b, char c) { return d(c) + 36 * (d(b) + 36 * d(a)); } 20 int z(int i) { return index('z', (i/10)+'0', (i%10)+'0'); } 21 22 enum class Op { AND, OR, XOR }; 23 24 class Gate { 25 public: 26 int x, y, z; 27 Op op; 28 29 bool ready() const { 30 return state[x] != -1 && state[y] != -1; 31 } 32 33 bool operate() const { /* Returns true if the operation flips a bit */ 34 auto oldstate = state[z]; 35 switch (op) { 36 case Op::AND: 37 state[z] = state[x] & state[y]; 38 break; 39 case Op::OR: 40 state[z] = state[x] | state[y]; 41 break; 42 case Op::XOR: 43 state[z] = state[x] ^ state[y]; 44 break; 45 } 46 return oldstate != state[z]; 47 } 48 }; 49 50 Op make_op(char c) { 51 switch (c) { 52 case '&': return Op::AND; 53 case '|': return Op::OR; 54 default: return Op::XOR; 55 } 56 } 57 58 int main() { 59 vector<Gate> gates; 60 fill(state, state + 36*36*36, -1); 61 string line; 62 63 while (getline(cin, line) && line != "") 64 state[index(line[0], line[1], line[2])] = line[5]-'0'; 65 66 while (getline(cin, line)) 67 gates.push_back(Gate { 68 .x = index(line[0], line[1], line[2]), 69 .y = index(line[6], line[7], line[8]), 70 .z = index(line[13], line[14], line[15]), 71 .op = make_op(line[4]) 72 }); 73 74 for (bool flag = true; flag; ) { 75 flag = false; 76 for (auto g : gates) 77 if (g.ready()) 78 flag = flag || g.operate(); 79 } 80 81 int64_t result = 0; 82 for (int64_t i = 0, j = 1; state[z(i)] != -1; i++, j *= 2) 83 result += (int64_t)state[z(i)] * j; 84 85 cout << result << endl; 86 87 return 0; 88 }