aboutsummaryrefslogtreecommitdiff
path: root/2016/src
diff options
context:
space:
mode:
Diffstat (limited to '2016/src')
-rw-r--r--2016/src/day12.cpp188
1 files changed, 188 insertions, 0 deletions
diff --git a/2016/src/day12.cpp b/2016/src/day12.cpp
new file mode 100644
index 0000000..1e231a5
--- /dev/null
+++ b/2016/src/day12.cpp
@@ -0,0 +1,188 @@
1#include <filesystem>
2#include <fstream>
3#include <iostream>
4#include <map>
5#include <optional>
6#include <string>
7#include <vector>
8
9using namespace std;
10
11namespace {
12
13enum class OpCode : uint8_t {
14 CPY_VAL,
15 CPY_REG,
16 INC,
17 DEC,
18 JMP,
19 JNZ,
20};
21
22struct Instruction {
23 Instruction(OpCode opCode, char reg)
24 : opCode{ opCode }
25 , reg{ reg }
26 {
27 }
28
29 Instruction(OpCode opCode, int val)
30 : opCode{ opCode }
31 , val{ val }
32 {
33 }
34
35 Instruction(OpCode opCode, char reg, int val)
36 : opCode{ opCode }
37 , reg{ reg }
38 , val{ val }
39 {
40 }
41
42 OpCode opCode;
43 optional<char> reg;
44 optional<int> val;
45};
46
47/*
48ostream&
49operator<<(ostream& os, const Instruction& instruction)
50{
51 cout << (int) instruction.opCode << ":";
52 if ( instruction.reg.has_value() ) {
53 cout << " reg: " << instruction.reg.value();
54 }
55 if ( instruction.val.has_value() ) {
56 cout << " val: " << instruction.val.value();
57 }
58 return os;
59}
60*/
61
62vector<Instruction>
63read_file(const filesystem::path& filename)
64{
65 ifstream input{ filename };
66
67 vector<Instruction> instructions;
68
69 for ( string line; getline(input, line); ) {
70 if ( line.starts_with("cpy") ) {
71 if ( isalpha(line.at(4)) != 0 ) {
72 auto from_reg = line.at(4);
73 auto to_reg = line.at(6);
74 instructions.emplace_back(OpCode::CPY_REG, to_reg, from_reg);
75 }
76 else {
77 auto val = stoi(&line.at(strlen("cpy ")));
78 auto reg = line.back();
79 instructions.emplace_back(OpCode::CPY_VAL, reg, val);
80 }
81 }
82 else if ( line.starts_with("inc") ) {
83 auto reg = line.at(4);
84 instructions.emplace_back(OpCode::INC, reg);
85 }
86 else if ( line.starts_with("dec") ) {
87 auto reg = line.at(4);
88 instructions.emplace_back(OpCode::DEC, reg);
89 }
90 else if ( line.starts_with("jnz 1") ) { // always jump!, WTF??
91 auto off = stoi(&line.at(strlen("jnz 1 ")));
92 instructions.emplace_back(OpCode::JMP, off);
93 }
94 else if ( line.starts_with("jnz") ) {
95 auto reg = line.at(4);
96 auto off = stoi(&line.at(strlen("jnz a ")));
97 instructions.emplace_back(OpCode::JNZ, reg, off);
98 }
99 else {
100 cerr << "unknown opcode..." << '\n';
101 }
102
103 // cout << line << " -> " << instructions.back() << '\n';
104 }
105
106 return instructions;
107}
108
109void
110execute(map<char, int>& memory, const vector<Instruction>& instructions)
111{
112 for ( size_t ip = 0; ip < instructions.size(); ) {
113 auto instruction = instructions.at(ip);
114
115 // cout << "#" << ip << " - " << memory['a'] << ", " << memory['b'] << ", " << memory['c'] << ", " << memory['d'] << ": " << (int) instruction.opCode << '\n';
116
117 switch ( instruction.opCode ) {
118 using enum OpCode;
119 case CPY_VAL:
120 memory[instruction.reg.value()] = instruction.val.value();
121 ++ip;
122 break;
123 case CPY_REG:
124 memory[instruction.reg.value()] = memory[static_cast<char>(instruction.val.value())];
125 ++ip;
126 break;
127 case INC:
128 memory[instruction.reg.value()]++;
129 ++ip;
130 break;
131 case DEC:
132 memory[instruction.reg.value()]--;
133 ++ip;
134 break;
135 case JMP:
136 ip += static_cast<size_t>(instruction.val.value());
137 break;
138 case JNZ:
139 if ( memory[instruction.reg.value()] != 0 ) {
140 ip += static_cast<size_t>(instruction.val.value());
141 }
142 else {
143 ++ip;
144 }
145 break;
146 }
147 }
148}
149
150void
151part1(const vector<Instruction>& instructions)
152{
153 map<char, int> memory;
154
155 memory['a'] = 0;
156 memory['b'] = 0;
157 memory['c'] = 0;
158 memory['d'] = 0;
159
160 execute(memory, instructions);
161
162 cout << "Part1: " << memory['a'] << '\n';
163}
164
165void
166part2(const vector<Instruction>& instructions)
167{
168 map<char, int> memory;
169
170 memory['a'] = 0;
171 memory['b'] = 0;
172 memory['c'] = 1;
173 memory['d'] = 0;
174
175 execute(memory, instructions);
176
177 cout << "Part2: " << memory['a'] << '\n';
178}
179
180} // namespace
181
182int
183main()
184{
185 const auto instructions = read_file("data/day12.txt");
186 part1(instructions);
187 part2(instructions);
188}