aoc

My solutions for the Advent of Code
git clone https://git.tronto.net/aoc
Download | Log | Files | Refs | README

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 }