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
|