aboutsummaryrefslogtreecommitdiff
path: root/src/2015/day23/aoc.cpp
blob: fd64a0609306603c4ba49d53c62a42a45f2205fe (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
#include "aoc.h"
#include <string.h>
#include <vector>
#include <functional>

namespace aoc2015 {
static int registers[2] = {0};

void execute(size_t i, const std::vector<line_view>& is);
void hlf(size_t i, const std::vector<line_view>& is, const char *p) {
  int x = *p == 'a' ? 0 : 1;
  registers[x] /= 2;
  execute(i+1, is);
}

void tpl(size_t i, const std::vector<line_view>& is, const char *p) {
  int x = *p == 'a' ? 0 : 1;
  registers[x] *= 3;
  execute(i+1, is);
}

void inc(size_t i, const std::vector<line_view>& is, const char *p) {
  int x = *p == 'a' ? 0 : 1;
  registers[x] += 1;
  execute(i+1, is);
}

static int get_number(const char *p) {
  int sign = *p == '+' ? 1 : -1;
  p++;
  int d{0};
  while(*p <= '9' && *p >= '0') {
    d = 10 * d + *p - '0';
    p++;
  }
  d *= sign;
  return d;
}

void jmp(size_t i, const std::vector<line_view>& is, const char *p) {
  int d = get_number(p);
  execute(i+d, is);
}

void jie(size_t i, const std::vector<line_view>& is, const char *p) {
  int x = *p == 'a' ? 0 : 1;
  p += 3;
  int d = registers[x] % 2 == 0 ? get_number(p) : 1;
  execute(i+d, is);
}

void jio(size_t i, const std::vector<line_view>& is, const char *p) {
  int x = *p == 'a' ? 0 : 1;
  p += 3;
  int d = registers[x] == 1 ? get_number(p) : 1;
  execute(i+d, is);
}

void execute(size_t i, const std::vector<line_view>& is) {
  if (i >= is.size()) {
    return;
  }
  line_view cmd = is[i];
  const char* p = cmd.line;
  struct {
    const char* ins;
    std::function<void(size_t, const std::vector<line_view>&, const char*)> f;
  } cmds[] = {
    {"hlf", hlf},
    {"tpl", tpl},
    {"inc", inc},
    {"jmp", jmp},
    {"jie", jie},
    {"jio", jio},
  };

  for(auto& c : cmds) {
    if (strncmp(p, c.ins, 3) == 0) {
      c.f(i, is, p+4);
      break;
    }
  }

}

std::pair<int, int> day23(line_view file) {
  std::vector<line_view> is;
  per_line(file, [&is](line_view lv){
      is.push_back(lv);
      return true;
  });

  execute(0, is);
  int a1 = registers[1];

  registers[0] = 1;
  registers[1] = 0;

  execute(0, is);
  int a2 = registers[1];
  return {a1, a2};
}

}