aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorkaiwu <kaiwu2004@gmail.com>2022-04-20 13:39:11 +0800
committerkaiwu <kaiwu2004@gmail.com>2022-04-20 13:39:11 +0800
commit787eb42f24cda88adfd0c041c08110581c0e11e1 (patch)
treea4eb28aa391608ebba909a1323f5e852925c462b /src
parentad940fa52f8bc45f07b5678eee4d94ee662e769b (diff)
downloadadvent-of-code-787eb42f24cda88adfd0c041c08110581c0e11e1.tar.gz
advent-of-code-787eb42f24cda88adfd0c041c08110581c0e11e1.zip
2018 day7
Diffstat (limited to 'src')
-rw-r--r--src/2018/day7/aoc.cpp33
-rw-r--r--src/2018/day7/aoc.h32
2 files changed, 61 insertions, 4 deletions
diff --git a/src/2018/day7/aoc.cpp b/src/2018/day7/aoc.cpp
index 6210814..354bfc8 100644
--- a/src/2018/day7/aoc.cpp
+++ b/src/2018/day7/aoc.cpp
@@ -2,8 +2,9 @@
namespace aoc2018 {
std::map<char, instruction*> instruction::instructions = {};
+size_t instruction::done_total = 0;
-void day7(line_view file, char sequence[]) {
+int day7(line_view file, char sequence[]) {
per_line(file, [](line_view lv) {
char p1 = *(lv.line + 5);
char p2 = *(lv.line + 36);
@@ -20,6 +21,36 @@ void day7(line_view file, char sequence[]) {
n->make_done();
n = instruction::next();
}
+
+ auto check = [](int s, instruction** w) {
+ if (*w != nullptr && (*w)->finished(s)) {
+ (*w)->make_done();
+ // std::cout << (*w)->label << " finishes at " << s << std::endl;
+ *w = nullptr;
+ }
+
+ if (*w == nullptr) {
+ instruction::next(w);
+ if (*w != nullptr) {
+ // std::cout << (*w)->label << " starts at " << s << std::endl;
+ (*w)->begin(s);
+ }
+ }
+ };
+
+ instruction::undo();
+ int second{0};
+ instruction* workers[5] = {nullptr, nullptr, nullptr, nullptr, nullptr};
+ // instruction* workers[2] = {nullptr, nullptr};
+ bool stop{false};
+ while (!stop) {
+ for (size_t i = 0; i < ARRAY_SIZE(workers) && !stop; i++) {
+ check(second, &workers[i]);
+ }
+ stop = instruction::all_done();
+ second += int(!stop);
+ }
+ return second;
}
} // namespace aoc2018
diff --git a/src/2018/day7/aoc.h b/src/2018/day7/aoc.h
index 25d127d..7ea6eb9 100644
--- a/src/2018/day7/aoc.h
+++ b/src/2018/day7/aoc.h
@@ -7,16 +7,26 @@ namespace aoc2018 {
struct instruction {
static std::map<char, instruction*> instructions;
+ static size_t done_total;
+
+ static bool all_done() { return done_total >= instructions.size(); }
static instruction* make(char x) {
auto it = instructions.find(x);
if (it == instructions.end()) {
- auto p = instructions.insert({x, new instruction{x, false, {}}});
+ auto p = instructions.insert({x, new instruction{x, false, INT32_MAX, {}}});
return p.first->second;
}
return it->second;
}
+ static void undo() {
+ for (auto& kv : instructions) {
+ kv.second->done = false;
+ }
+ done_total = 0;
+ }
+
static instruction* next() {
instruction* n = nullptr;
for (auto& kv : instructions) {
@@ -33,12 +43,27 @@ struct instruction {
return n; // if nullptr all done
}
+ static void next(instruction** n) {
+ for (auto& kv : instructions) {
+ if (kv.second->ready() && kv.second->start == INT32_MAX) {
+ *n = kv.second;
+ return;
+ }
+ }
+ *n = nullptr;
+ }
+
char label;
bool done;
+ int start;
std::set<instruction*> deps;
void add_dependency(instruction* x) noexcept { deps.insert(x); }
- void make_done() noexcept { done = true; }
+ void make_done() noexcept {
+ done = true;
+ done_total += 1;
+ }
+ void begin(int s) noexcept { start = s; }
bool operator<(const instruction& other) const noexcept { return label < other.label; }
bool ready(const std::set<instruction*> ds) const noexcept {
@@ -50,9 +75,10 @@ struct instruction {
return true;
}
+ bool finished(int s) const noexcept { return start != INT32_MAX && s >= start + label - 'A' + 1 + 60; }
bool ready() const noexcept { return !done && (deps.empty() || ready(deps)); }
};
-void day7(line_view, char[]);
+int day7(line_view, char[]);
} // namespace aoc2018