aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--2015/src/day23.cpp144
1 files changed, 144 insertions, 0 deletions
diff --git a/2015/src/day23.cpp b/2015/src/day23.cpp
new file mode 100644
index 0000000..80281da
--- /dev/null
+++ b/2015/src/day23.cpp
@@ -0,0 +1,144 @@
1#include <fstream>
2#include <iostream>
3#include <string>
4#include <tuple>
5#include <vector>
6using namespace std;
7
8enum Instruction {
9 Half_A,
10 Half_B,
11 Triple_A,
12 Triple_B,
13 Inc_A,
14 Inc_B,
15 Jmp,
16 Jmp_Even_A,
17 Jmp_Even_B,
18 Jmp_One_A,
19 Jmp_One_B
20};
21
22vector<tuple<Instruction, int>>
23read_file(string_view filename)
24{
25 fstream input{ filename };
26
27 vector<tuple<Instruction, int>> instructions;
28 for ( string line; getline(input, line); ) {
29 if ( line == "hlf a" ) {
30 instructions.emplace_back(Half_A, 0);
31 }
32 else if ( line == "hlf b" ) {
33 instructions.emplace_back(Half_B, 0);
34 }
35 else if ( line == "tpl a" ) {
36 instructions.emplace_back(Triple_A, 0);
37 }
38 else if ( line == "tpl b" ) {
39 instructions.emplace_back(Triple_B, 0);
40 }
41 else if ( line == "inc a" ) {
42 instructions.emplace_back(Inc_A, 0);
43 }
44 else if ( line == "inc b" ) {
45 instructions.emplace_back(Inc_B, 0);
46 }
47 else if ( line.starts_with("jmp ") ) {
48 auto offset = stoi(line.substr(4));
49 instructions.emplace_back(Jmp, offset);
50 }
51 else if ( line.starts_with("jie a, ") ) {
52 auto offset = stoi(line.substr(7));
53 instructions.emplace_back(Jmp_Even_A, offset);
54 }
55 else if ( line.starts_with("jie b, ") ) {
56 auto offset = stoi(line.substr(7));
57 instructions.emplace_back(Jmp_Even_B, offset);
58 }
59 else if ( line.starts_with("jio a, ") ) {
60 auto offset = stoi(line.substr(7));
61 instructions.emplace_back(Jmp_One_A, offset);
62 }
63 else if ( line.starts_with("jio b, ") ) {
64 auto offset = stoi(line.substr(7));
65 instructions.emplace_back(Jmp_One_B, offset);
66 }
67 else {
68 cerr << "unknown instruction: " << line << endl;
69 }
70 }
71 return instructions;
72}
73
74int
75eval(const vector<tuple<Instruction, int>>& instructions, int a, int b)
76{
77 for ( size_t ip = 0; ip < instructions.size(); ) {
78 const auto [instruction, offset] = instructions[ip++];
79 switch ( instruction ) {
80 case Half_A:
81 a /= 2;
82 break;
83 case Half_B:
84 b /= 2;
85 break;
86 case Triple_A:
87 a *= 3;
88 break;
89 case Triple_B:
90 b *= 3;
91 break;
92 case Inc_A:
93 a++;
94 break;
95 case Inc_B:
96 b++;
97 break;
98 case Jmp:
99 ip = (ip - 1) + size_t(offset);
100 break;
101 case Jmp_Even_A:
102 if ( a % 2 == 0 ) {
103 ip = (ip - 1) + size_t(offset);
104 }
105 break;
106 case Jmp_Even_B:
107 if ( b % 2 == 0 ) {
108 ip = (ip - 1) + size_t(offset);
109 }
110 break;
111 case Jmp_One_A:
112 if ( a == 1 ) {
113 ip = (ip - 1) + size_t(offset);
114 }
115 break;
116 case Jmp_One_B:
117 if ( b == 1 ) {
118 ip = (ip - 1) + size_t(offset);
119 }
120 break;
121 }
122 }
123 return b;
124}
125
126void
127part1(const vector<tuple<Instruction, int>>& instructions)
128{
129 cout << eval(instructions, 0, 0) << endl;
130}
131
132void
133part2(const vector<tuple<Instruction, int>>& instructions)
134{
135 cout << eval(instructions, 1, 0) << endl;
136}
137
138int
139main()
140{
141 auto instructions = read_file("data/day23.txt");
142 part1(instructions);
143 part2(instructions);
144}