-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathday_23a.cpp
124 lines (115 loc) · 3.79 KB
/
day_23a.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <fstream>
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
#include <variant>
#include <queue>
// HINT: When the puzzle says X or Y, unless it specifies register, X or Y can be a number
// JNZ 1 3 is a possibility
// add p b is a possibility
enum class InstructionType{
UNKNOWN, SND, SUB, SET, ADD, MUL, MOD, RCV, JGZ
};
struct Instruction {
std::string line;
InstructionType type;
std::array<std::variant<long long, char>,2> args;
long long reg() const {
return std::get<char>(args[0]);
}
long long get_value (const int idx, std::unordered_map<char, long long>& regs) const {
return args[idx].index() == 0 ? std::get<long long>(args[idx]) : regs[std::get<char>(args[idx])];
}
};
InstructionType parse_type(const std::string& instr) {
if (instr == "set") {
return InstructionType::SET;
} else if (instr == "sub") {
return InstructionType::SUB;
} else if (instr == "mul") {
return InstructionType::MUL;
} else if (instr == "jnz") {
return InstructionType::JGZ;
}
std::cout << "UNKNOWN" << '\n';
exit(0);
return InstructionType::UNKNOWN;
}
std::vector<Instruction> parse_instructions (std::ifstream& file) {
std::vector<Instruction> instructions;
std::string line;
while(std::getline(file, line)) {
// std::cout << line << '\n';
Instruction i;
i.line = line;
i.type = parse_type(line.substr(0, 3));
int next = 0;
if (line[4] >= 'a' && line[4] <='z') {
std::cout << "Args 1 is a register: " << char(line[4]) <<'\n';
i.args[0] = char(line[4]);
next = 6;
} else {
next = line.find(' ', 4);
if (next == std::string::npos) {
// std::cout << "npos" << '\n';
next == line.size();
}
std::cout << "Args 1 is a number: " << std::stoi(line.substr(4, next - 4)) << '\n';
i.args[0] = std::stoi(line.substr(4, next - 4));
if (next != std::string::npos) {
next++;
}
}
// std::cout << line.size() << ' ' << next << '\n';
if (line.size() >= next) {
// std::cout << "Second args exists; size == " << line.size() << " > " << next << '\n';
if (line[next] >= 'a' && line[next] <='z') {
i.args[1] = char(line[next]);
std::cout << "Args 2 is a register: " << char(line[next]) <<'\n';
} else {
std::cout << "Args 2 is a number: " << std::stoi(line.substr(next, line.size() - next)) << '\n';
i.args[1] = std::stoi(line.substr(next, line.size() - next));
}
}
instructions.push_back(i);
}
// exit(0);
return instructions;
}
int main(int argc, char* argv[]) {
const std::string input = (argc > 1) ? argv[1] : "../input/day_18_input" ;
std::ifstream file(input);
const std::vector<Instruction> instructions = parse_instructions(file);
std::unordered_map<char, long long> regs;
for (char c = 'a'; c <= 'h'; c++) {
regs[c] = 0;
}
std::size_t ans = 0;
std::size_t instruction_ptr = 0;
while (instruction_ptr < instructions.size()) {
const auto& instruction = instructions[instruction_ptr];
if (instruction.type == InstructionType::SET) {
regs[instruction.reg()] = instruction.get_value(1, regs);
instruction_ptr++;
} else if (instruction.type == InstructionType::SUB) {
regs[instruction.reg()] -= instruction.get_value(1, regs);
instruction_ptr++;
} else if (instruction.type == InstructionType::MUL) {
regs[instruction.reg()] *= instruction.get_value(1, regs);
instruction_ptr++;
ans++;
} else if (instruction.type == InstructionType::JGZ) {
if(instruction.get_value(0, regs) != 0) {
instruction_ptr += instruction.get_value(1, regs);
} else {
instruction_ptr++;
}
} else {
std::cout << "UNKNOWN" << '\n';
exit(0);
}
}
std::cout << ans << '\n';
return 0;
}