aboutsummaryrefslogtreecommitdiff
path: root/src/2017/day23/aoc.cpp
blob: 4d44c245578b864c00707447cca9a52b303d633f (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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "aoc.h"

namespace aoc2017 {

static int64_t& get(char x, int64_t rs[26]) { return rs[x - 'a']; }
static void get_number(const char** pp, int64_t* d) {
  const char* p = *pp;
  int sign = 1;
  if (*p == '-') {
    sign = -1;
    p++;
  }
  while (*p >= '0' && *p <= '9') {
    *d = *d * 10 + *p - '0';
    p++;
  }
  *d *= sign;
  *pp = p;
}

static int64_t get_number(const char* p, int64_t rs[26]) {
  int64_t d{0};
  if (*p == '-' || (*p >= '0' && (*p <= '9'))) {
    get_number(&p, &d);
  } else {
    d = get(*p, rs);
  }
  return d;
}

typedef void (*f23)(size_t* i, const char* p1, const char* p2, int64_t rs[26]);

static void set(size_t* i, const char* p1, const char* p2, int64_t rs[26]) {
  get(*p1, rs) = get_number(p2, rs);
  *i += 1;
}

static void sub(size_t* i, const char* p1, const char* p2, int64_t rs[26]) {
  get(*p1, rs) -= get_number(p2, rs);
  *i += 1;
}

static void mul(size_t* i, const char* p1, const char* p2, int64_t rs[26]) {
  get(*p1, rs) *= get_number(p2, rs);
  *i += 1;
}

static void jnz(size_t* i, const char* p1, const char* p2, int64_t rs[26]) {
  auto d1 = get_number(p1, rs);
  auto d2 = get_number(p2, rs);
  *i += d1 != 0 ? d2 : 1;
}

static struct {
  f23 f;
  const char* s;
  int c;
} fs[4] = {{set, "set", 0}, {sub, "sub", 0}, {mul, "mul", 0}, {jnz, "jnz", 0}};

static size_t exec(size_t index, const std::vector<line_view>& todos, int64_t rs[26]) {
  if (index < todos.size()) {
    auto& todo = todos[index];
    const char* p = todo.line;
    auto match = [](const char* p, const char* p0) -> bool {
      for (int i = 0; i < 3; i++) {
        if (*(p + i) != *(p0 + i)) {
          return false;
        }
      }
      return true;
    };

    for (auto& fx : fs) {
      if (match(p, fx.s)) {
        fx.c += 1;
        fx.f(&index, p + 4, p + 6, rs);
        break;
      }
    }
  }
  return index;
}

static void part1(std::vector<line_view> todos) {
  size_t index{0};
  int64_t rs[26] = {0};

  while (index < todos.size()) {
    index = exec(index, todos, rs);
  }
}

static void part2(std::vector<line_view> todos) {
  size_t index{0};
  int64_t rs[26] = {0};
  rs[0] = 1; // a is 1
  auto print = [](int64_t is[26]) {
    for (char c = 'a'; c <= 'h'; c++) {
      printf("%c[%ld] ", c, is[c - 'a']);
    }
    printf("\n");
  };

  while (index < todos.size()) {
    std::cout << todos[index] << " ";
    index = exec(index, todos, rs);
    print(rs);
  }
}

std::pair<int64_t, int64_t> day23(line_view file) {
  std::vector<line_view> todos;
  per_line(file, [&todos](line_view lv) {
    todos.push_back({lv.line, lv.length - 1});
    return true;
  });

  part1(todos);
  int64_t t0 = fs[2].c;
  part2(todos);

  return {t0, 0};
}
} // namespace aoc2017