Branch data Line data Source code
1 : : #include <iostream>
2 : : #include <vector>
3 : : #include <fstream>
4 : : #include <map>
5 : : #include <cstdint>
6 : : #include <algorithm>
7 : : #include <sstream>
8 : : #include <ranges>
9 : : using namespace std;
10 : :
11 : : vector<int64_t> instructions;
12 : : int64_t A;
13 : : int64_t B;
14 : : int64_t C;
15 : :
16 : 6208 : int64_t comboValue(int64_t operand) {
17 [ + + + + : 6208 : return operand < 4 ? operand : operand == 4 ? A : operand == 5 ? B : C;
+ - ]
18 : : }
19 : :
20 : 31 : int64_t rec(const vector<int64_t>& program, size_t instructionPointer, int64_t current = 0) {
21 [ + + ]: 190 : for (int64_t i = 0; i < 8; ++i) {
22 : 175 : int64_t newCurrent = (current << 3) + i;
23 : 175 : vector<int64_t> result;
24 : :
25 : 175 : A = newCurrent;
26 [ + + ]: 12591 : for (int ip = 0; ip < instructions.size();) {
27 : 12416 : int64_t opcode = instructions[ip++];
28 : 12416 : int64_t operand = instructions[ip++];
29 [ + + + + : 12416 : switch (opcode) {
+ + - + ]
30 : 1552 : case 0: // adv
31 : 1552 : A /= (1 << comboValue(operand));
32 : 1552 : break;
33 : 3104 : case 1: // bxl
34 : 3104 : B ^= operand;
35 : 3104 : break;
36 : 1552 : case 2: // bst
37 : 1552 : B = comboValue(operand) & 7;
38 : 1552 : break;
39 : 1552 : case 3: // jnz
40 [ + + ]: 1552 : if (A) {
41 : 1377 : ip = operand;
42 : : }
43 : 1552 : break;
44 : 1552 : case 4: // bxc
45 : 1552 : B ^= C;
46 : 1552 : break;
47 : 1552 : case 5: // out
48 : 1552 : result.push_back(comboValue(operand) & 7);
49 : 1552 : break;
50 : 0 : case 6: // bdv
51 : 0 : B = A / (1 << comboValue(operand));
52 : 0 : break;
53 : 1552 : default: // cdv
54 : 1552 : C = A / (1 << comboValue(operand));
55 : 1552 : break;
56 : : }
57 : : }
58 : :
59 [ + + ]: 175 : if (equal(result.begin(), result.end(), program.begin() + instructionPointer)) {
60 [ + + ]: 31 : if (instructionPointer == 0) {
61 : 1 : return newCurrent;
62 : : }
63 : 30 : auto result = rec(program, instructionPointer - 1, newCurrent);
64 [ + + ]: 30 : if (result != -1) {
65 : 15 : return result;
66 : : }
67 : : }
68 [ + + ]: 175 : }
69 : 15 : return -1;
70 : : }
71 : :
72 : 2 : int main() {
73 : 2 : ifstream input("input.txt");
74 [ + + ]: 2 : if (!input) {
75 : 1 : cerr << "Error: Could not open input file.\n";
76 : 1 : return 1;
77 : : }
78 : 1 : string line;
79 : 1 : string programOutput;
80 : 1 : vector<string> contents = ranges::istream_view<string>(input) | ranges::to<vector<string>>();
81 : :
82 : 17 : instructions = contents[10] | views::split(',') | views::transform([](auto&& part) { return part[0] - '0'; }) | ranges::to<vector<int64_t>>();
83 : :
84 : 1 : cout << rec(instructions, instructions.size() - 1) << endl;
85 [ + + ]: 3 : }
|