aboutsummaryrefslogtreecommitdiff
path: root/src/2015/day19/aoc.cpp
blob: 68f5f525e9841458150e776eb0c51cb1ebd79fbb (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
#include "aoc.h"

namespace aoc2015 {

std::pair<int, int> day19(line_view file) {
  molecule m;
  per_line(file, [&m](line_view lv) {
    m.parse(lv);
    return true;
  });
  std::map<int, std::vector<molecule::change>> changes;
  m.check(changes);
  // int shortest = INT32_MAX;
  // m.deduct(m.original, 0, &shortest);
  // m.transfer("e", 0, &shortest);
  int steps = 0;

  line_view lv = m.original;
  std::vector<molecule::pattern> ps;

  do {
    lv = m.replace(lv, &steps);
    // printf("%d\n", steps);

    ps.clear();
    const char* x = nullptr;
    m.parse_pattern(lv, 0, ps, &x);
    // std::for_each(ps.begin(), ps.end(),
    //              [](molecule::pattern p) { std::cout << p.depth << " -> " << p.lv << std::endl; });
    if (ps[0].lv == "e") {
      break;
    }
    if (ps[0].lv.contains("Y")) {
      std::vector<line_view> ys;
      m.parse_y(ps[0].lv, ys);
      for (auto y : ys) {
        if (m.transfers.find(y) == m.transfers.end()) {
          line_view to = m.deduce(y, &steps);
          lv = m.replace(lv, {y, to}, y.line);
          break;
        }
      }
    } else {
      line_view to = m.deduce(ps[0].lv, &steps);
      if (!(to == ps[0].lv)) {
        lv = m.replace(lv, {ps[0].lv, to}, ps[0].lv.line);
      } else {
        lv = m.deduce(lv, ps[0].lv.line - 2, &steps);
      }
    }
  } while (true);

  return {m.distinct(changes), steps};
}

} // namespace aoc2015