aboutsummaryrefslogtreecommitdiff
path: root/src/2018/day7/aoc.cpp
blob: 6d6a723a8c20c0988cc520c572b488fe2c1610ef (plain)
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
#include "aoc.h"
#include <algorithm>

namespace aoc2018 {
std::map<char, instruction*> instruction::instructions = {};
size_t instruction::done_total = 0;

void print() {
  for (auto& kv : instruction::instructions) {
    std::cout << kv.second->label << " -> ";
    for (auto x : kv.second->deps) {
      std::cout << x->label << " ";
    }
    std::cout << std::endl;
  }
}

int day7(line_view file, char sequence[]) {
  per_line(file, [](line_view lv) {
    char p1 = *(lv.line + 5);
    char p2 = *(lv.line + 36);
    instruction* i1 = instruction::make(p1);
    instruction* i2 = instruction::make(p2);
    i2->add_dependency(i1);
    return true;
  });

  instruction* n = instruction::next();
  int i{0};
  while (n != nullptr) {
    sequence[i++] = n->label;
    n->make_done();
    n = instruction::next();
  }

  // print();

  auto check = [](int s, instruction** w, size_t size) {
    for (size_t i = 0; i < size; i++) {
      if (w[i] != nullptr && w[i]->finished(s)) {
        (w[i])->make_done();
        w[i] = nullptr;
      }
    }

    for (size_t i = 0; i < size; i++) {
      if (w[i] == nullptr) {
        instruction::next(&w[i]);
        if (w[i] != nullptr) {
          w[i]->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) {
    check(second, workers, ARRAY_SIZE(workers));
    stop = instruction::all_done();
    second += int(!stop);
  }
  return second;
}

} // namespace aoc2018