aboutsummaryrefslogtreecommitdiff
path: root/src/2017/day7/aoc.cpp
blob: 32a59ed6f4abf176403a020857d2fd9e8d013710 (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
70
71
72
73
74
75
76
77
78
79
80
81
#include "aoc.h"
#include <unordered_map>

namespace aoc2017 {

void fix_subs(std::unordered_map<line_view, disc*>& ds) {
  for (auto& kv : ds) {
    if (kv.second->xp != nullptr) {
      const char* p1 = kv.second->xp;
      const char* p = p1;
      while (*p != '\n') {
        if (*p == ',') {
          kv.second->subs.push_back(ds[{p1, p}]);
          p1 = p + 2;
        }
        p++;
      }
      kv.second->subs.push_back(ds[{p1, p}]);
    }
  }
}

void depth(disc* d, int* dh) {
  if (d->subs.size() > 0) {
    *dh += 1;
    depth(d->subs[0], dh);
  }
}

void weight(disc* d, int* w) {
  int total{0};
  for (disc* x : d->subs) {
    weight(x, &x->total);
    total += x->total;
  }
  *w += d->weight + total;
}

void print(disc* d, int depth) {
  for (int i = 0; i < depth; i++) {
    printf(" ");
  }
  std::cout << d->name << "(" << d->total << "," << d->weight << ")" << std::endl;
  if (depth < 3) {
    for (disc* x : d->subs) {
      print(x, depth + 1);
    }
  }
}

void day7(line_view file, char name[]) {
  std::unordered_map<line_view, disc*> ds;
  per_line(file, [&ds](line_view lv) {
    const char* p = lv.contains("(");
    line_view name{lv.line, p - 1};
    ds.insert({name, new disc{lv, p}});
    return true;
  });
  fix_subs(ds);

  line_view x;
  int max{INT32_MIN};
  for (auto& kv : ds) {
    int d{1};
    depth(kv.second, &d);
    if (d > max) {
      max = d;
      x = kv.first;
    }
  }
  int i{0};
  per_char(x, [&name, &i](char c) {
    name[i++] = c;
    return true;
  });

  weight(ds[x], &ds[x]->total);
  // print(ds[x], 0);
}

} // namespace aoc2017