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
|
#include "aoc.h"
namespace aoc2016 {
static int registers[4] = {7, 0, 0, 0};
static int& get(int i) { return registers[i]; }
// c = a,b,c,d
static int& get(char c) { return get(c - 'a'); }
struct instruction23 {
mutable size_t toggles = 0;
line_view todo;
instruction23(line_view l) : todo(l) {}
int which() {
std::cout << todo << std::endl;
const char* p = todo.line;
switch (*p) {
case 'c':
return 0;
case 'i':
return 1;
case 'd':
return 2;
case 'j':
return 3;
case 't':
return 4;
default:
break;
}
return 4;
}
};
static void get_number(const char** pp, int* d) {
const char* p = *pp;
int sign = 1;
if (*p == '-') {
sign = -1;
p += 1;
}
while (*p >= '0' && *p <= '9') {
*d = *d * 10 + *p - '0';
p++;
}
*d *= sign;
*pp = p;
}
typedef void (*todo_f)(size_t*, const char*, const std::vector<instruction23>&);
static void cpy(size_t* i, const char* p, const std::vector<instruction23>& todos) {
int d{0};
if (*p >= '0' && *p <= '9') {
get_number(&p, &d);
p += 1;
} else {
d = get(*p);
p += 2;
}
get(*p) = d;
*i += 1;
}
static void inc(size_t* i, const char* p, const std::vector<instruction23>& todos) {
get(*p) += 1;
*i += 1;
}
static void dec(size_t* i, const char* p, const std::vector<instruction23>& todos) {
get(*p) -= 1;
*i += 1;
}
static void jnz(size_t* i, const char* p, const std::vector<instruction23>& todos) {
bool condition = *p >= '0' && *p <= '9' ? *p - '0' : get(*p) != 0;
if (condition) {
p += 2;
int offset{0};
get_number(&p, &offset);
*i += offset;
} else {
*i += 1;
}
}
static void tgl(size_t* i, const char* p, const std::vector<instruction23>& todos) {
size_t next = *i + get(*p);
if (next < todos.size()) {
todos[next].toggles += 1;
}
*i += 1;
}
static void non(size_t* i, const char* p, const std::vector<instruction23>&) { *i += 1; }
static size_t exec(size_t i, const std::vector<instruction23>& todos) {
if (i < todos.size()) {
todo_f fs[6] = {cpy, inc, dec, jnz, tgl, non};
auto d = todos[i];
fs[d.which()](&i, d.todo.line + 4, todos);
}
return i;
}
std::pair<int64_t, int64_t> day23(line_view file) {
std::vector<instruction23> todos;
per_line(file, [&todos](line_view lv) {
todos.emplace_back(line_view{lv.line, lv.length - 1});
return true;
});
size_t i = 0;
while (i < todos.size()) {
i = exec(i, todos);
}
return {0, 0};
}
} // namespace aoc2016
|