aboutsummaryrefslogtreecommitdiff
path: root/2024/src
diff options
context:
space:
mode:
Diffstat (limited to '2024/src')
-rw-r--r--2024/src/day17.cpp110
1 files changed, 110 insertions, 0 deletions
diff --git a/2024/src/day17.cpp b/2024/src/day17.cpp
new file mode 100644
index 0000000..f0d1010
--- /dev/null
+++ b/2024/src/day17.cpp
@@ -0,0 +1,110 @@
1#include <fstream>
2#include <iostream>
3#include <map>
4#include <sstream>
5#include <string>
6#include <tuple>
7#include <vector>
8using namespace std;
9
10using program_type = vector<unsigned long>;
11using registers_type = map<char, unsigned long>;
12
13vector<string>
14split(const string& line, char sep = ' ')
15{
16 vector<string> parts;
17 stringstream input{ line };
18
19 for ( string part; getline(input, part, sep); ) {
20 parts.emplace_back(part);
21 }
22
23 return parts;
24}
25
26tuple<registers_type, program_type>
27read_file(string_view filename)
28{
29 fstream input{ filename };
30
31 map<char, unsigned long> registers;
32 vector<unsigned long> program;
33
34 for ( string line; getline(input, line); ) {
35 if ( line.empty() ) {
36 continue;
37 }
38
39 const auto parts = split(line, ':');
40
41 if ( parts[0] == "Register A" ) {
42 registers['A'] = stoul(parts[1]);
43 }
44 else if ( parts[0] == "Register B" ) {
45 registers['B'] = stoul(parts[1]);
46 }
47 else if ( parts[0] == "Register C" ) {
48 registers['C'] = stoul(parts[1]);
49 }
50 else if ( parts[0] == "Program" ) {
51 for ( const auto& value: split(parts[1], ',') ) {
52 program.emplace_back(stoul(value));
53 }
54 }
55 }
56
57 return { registers, program };
58}
59
60void
61part1(const tuple<registers_type, program_type>& data)
62{
63 auto [registers, program] = data;
64
65 for ( unsigned long ip = 0; ip < program.size(); ) {
66 const auto opcode = program.at(ip++);
67 const auto operand = program.at(ip++);
68 const auto value = (operand < 4) ? operand : registers[char('A' + operand - 4)];
69
70 switch ( opcode ) {
71 case 0: // adv
72 registers['A'] >>= value;
73 break;
74 case 1: // bxl
75 registers['B'] ^= operand;
76 break;
77 case 2: // bst
78 registers['B'] = value % 8;
79 break;
80 case 3: // jnz
81 if ( registers['A'] != 0 ) {
82 ip = operand;
83 }
84 break;
85 case 4:
86 registers['B'] ^= registers['C'];
87 break;
88 case 5:
89 cout << (value & 7) << ',';
90 break;
91 case 6:
92 registers['B'] = registers['A'] >> value;
93 break;
94 case 7:
95 registers['C'] = registers['A'] >> value;
96 break;
97 default:
98 cout << "Error" << endl;
99 return;
100 }
101 }
102 cout << endl;
103}
104
105int
106main()
107{
108 auto data = read_file("data/day17.txt");
109 part1(data);
110}