-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy path10.cpp
113 lines (94 loc) · 2.64 KB
/
10.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
#include <cctype>
#include <chrono>
#include <iostream>
#include <regex>
#include <unordered_map>
#include <utility>
#include <vector>
using std::string;
using std::vector;
struct Bot {
vector<int>* targets[2];
vector<int> chips;
};
struct Bin {
vector<int> chips;
};
vector<int> parse_ints_in_line(const string& line) {
vector<int> r;
for (size_t i = 0; i < line.length(); i++) {
if (!std::isdigit(line[i])) {
continue;
}
// at number, parse it into vec
r.push_back(std::stoi(&line[i]));
// skip
while (line[i] >= '0' && line[i] <= '9') {
i++;
}
}
return r;
}
int main() {
auto tstart = std::chrono::high_resolution_clock::now();
int pt1 = 0;
int pt2 = 0;
std::unordered_map<int, struct Bot> bots;
std::unordered_map<int, struct Bin> output_bins;
std::string input;
std::regex rx(
"^bot (\\d+) gives low to (\\w+) (\\d+) and high to (\\w+) (\\d+)$");
std::smatch matches;
while (std::getline(std::cin, input)) {
if (input[0] == 'v') {
vector nums = parse_ints_in_line(input);
bots[nums[1]].chips.push_back(nums[0]);
} else {
std::regex_match(input, matches, rx);
int b = std::stoi(matches[1].str());
int tlow = std::stoi(matches[3].str());
int thigh = std::stoi(matches[5].str());
if (matches[2].compare("output") == 0) {
bots[b].targets[0] = &output_bins[tlow].chips;
} else {
bots[b].targets[0] = &bots[tlow].chips;
}
if (matches[4].compare("output") == 0) {
bots[b].targets[1] = &output_bins[thigh].chips;
} else {
bots[b].targets[1] = &bots[thigh].chips;
}
}
}
while (true) {
int actions = 0;
for (auto& [id, bot] : bots) {
if (bot.chips.size() == 2) {
int low = std::min(bot.chips[0], bot.chips[1]);
int high = std::max(bot.chips[0], bot.chips[1]);
bot.chips.clear();
if (low == 17 && high == 61) {
pt1 = id;
}
bot.targets[0]->push_back(low);
bot.targets[1]->push_back(high);
actions++;
}
}
// stop if in a stable state (all chips have been distributed)
if (actions == 0) {
break;
}
}
pt2 = output_bins[0].chips[0] * output_bins[1].chips[0] *
output_bins[2].chips[0];
std::cout << "--- Day 10: Balance Bots ---\n";
std::cout << "Part 1: " << pt1 << "\n";
std::cout << "Part 2: " << pt2 << "\n";
auto tstop = std::chrono::high_resolution_clock::now();
auto duration =
std::chrono::duration_cast<std::chrono::microseconds>(tstop - tstart);
std::cout << "Time: " << duration.count() << " μs"
<< "\n";
return EXIT_SUCCESS;
}