aboutsummaryrefslogtreecommitdiff
path: root/2017/src/day23.cpp
diff options
context:
space:
mode:
authorThomas Schmucker <ts@its1.de>2025-11-07 12:04:46 +0100
committerThomas Schmucker <ts@its1.de>2025-11-07 12:04:46 +0100
commitbdd35a7bee7f23c912d0c453abc263805d8d8ccf (patch)
treedcd06076d36124ea8fdd16ea19db79717dde074c /2017/src/day23.cpp
parent756f22d58bb198b8f34589c112e1003614ccdcd6 (diff)
downloadadvent-of-code-bdd35a7bee7f23c912d0c453abc263805d8d8ccf.tar.gz
advent-of-code-bdd35a7bee7f23c912d0c453abc263805d8d8ccf.tar.bz2
advent-of-code-bdd35a7bee7f23c912d0c453abc263805d8d8ccf.zip
aoc 2017, days 21-25
Diffstat (limited to '2017/src/day23.cpp')
-rw-r--r--2017/src/day23.cpp158
1 files changed, 158 insertions, 0 deletions
diff --git a/2017/src/day23.cpp b/2017/src/day23.cpp
new file mode 100644
index 0000000..1f4b960
--- /dev/null
+++ b/2017/src/day23.cpp
@@ -0,0 +1,158 @@
1#include <charconv>
2#include <filesystem>
3#include <fstream>
4#include <iostream>
5#include <map>
6#include <sstream>
7#include <string>
8#include <vector>
9
10using namespace std;
11
12namespace {
13
14template<typename T>
15struct CPU {
16 [[nodiscard]]
17 T get(const string& ref)
18 {
19 T value{};
20 auto [ptr, ec] = from_chars(ref.data(), ref.data() + ref.size(), value);
21
22 if ( ec == errc() ) {
23 return value;
24 }
25
26 return memory[ref];
27 }
28
29 void set(const string& ref, T value)
30 {
31 memory[ref] = value;
32 }
33
34 void sub(const string& ref, T value)
35 {
36 memory[ref] -= value;
37 }
38
39 void mul(const string& ref, T value)
40 {
41 memory[ref] *= value;
42 }
43
44 T execute(const vector<vector<string>>& code)
45 {
46 int mul_executed = 0;
47
48 for ( size_t ip = 0; ip < code.size(); ++ip ) {
49 const auto& line = code.at(ip);
50 const auto& opcode = line.at(0);
51
52 if ( opcode == "set" ) {
53 set(line.at(1), get(line.at(2)));
54 }
55 else if ( opcode == "sub" ) {
56 sub(line.at(1), get(line.at(2)));
57 }
58 else if ( opcode == "mul" ) {
59 ++mul_executed;
60 mul(line.at(1), get(line.at(2)));
61 }
62 else if ( opcode == "jnz" ) {
63 auto value = get(line.at(1));
64 if ( value != 0 ) {
65 auto offset = get(line.at(2));
66 ip += static_cast<size_t>(offset - 1);
67 }
68 }
69 else {
70 cerr << "unknown opcode: " << opcode << '\n';
71 return -1;
72 }
73 }
74 return mul_executed;
75 }
76
77 map<string, T> memory;
78};
79
80vector<string>
81split(const string& line)
82{
83 stringstream strm{ line };
84 vector<string> data;
85
86 for ( string line; strm >> line; ) {
87 data.emplace_back(line);
88 }
89
90 return data;
91}
92
93vector<vector<string>>
94read_file(const filesystem::path& filename)
95{
96 ifstream file{ filename };
97 vector<vector<string>> data;
98
99 for ( string line; getline(file, line); ) {
100 const auto parts = split(line);
101 data.emplace_back(parts);
102 }
103
104 return data;
105}
106
107void
108part1(const vector<vector<string>>& code)
109{
110 CPU<long> cpu{};
111
112 cout << "Part1: " << cpu.execute(code) << '\n';
113}
114
115void
116part2(const vector<vector<string>>& code)
117{
118 CPU<long> cpu{};
119 cpu.memory["a"] = 1;
120
121 // execute only initialization code
122 cpu.execute({ code.begin(), code.begin() + 8 });
123
124 auto b_start = cpu.memory["b"];
125 auto c_end = cpu.memory["c"];
126
127 auto is_prime = [](long n) {
128 if ( n < 2 ) {
129 return false;
130 }
131 for ( long i = 2; i * i <= n; ++i ) {
132 if ( n % i == 0 ) {
133 return false;
134 }
135 }
136 return true;
137 };
138
139 const long step = 17;
140 long memory_h = 0;
141 for ( long b = b_start; b <= c_end; b += step ) {
142 if ( !is_prime(b) ) {
143 ++memory_h;
144 }
145 }
146
147 cout << "Part2: " << memory_h << '\n';
148}
149
150} // namespace
151
152int
153main()
154{
155 auto instr = read_file("data/day23.txt");
156 part1(instr);
157 part2(instr);
158}