diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/2018/day7/aoc.cpp | 33 | ||||
-rw-r--r-- | src/2018/day7/aoc.h | 32 |
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 |