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
|
#include "aoc.h"
#include <set>
namespace aoc2017 {
static int radias = 12; // demo 25/2 = 12 input
enum facing {
f_up,
f_down,
f_right,
f_left,
};
struct vpos {
int x;
int y;
facing f;
};
static vpos turn_right(vpos p) {
facing fs[4] = {f_right, f_left, f_down, f_up};
return {p.x, p.y, fs[(int)p.f]};
}
static vpos turn_left(vpos p) {
facing fs[4] = {f_left, f_right, f_up, f_down};
return {p.x, p.y, fs[(int)p.f]};
}
static vpos move(vpos p) {
vpos vs[4] = {
{p.x, p.y - 1, p.f},
{p.x, p.y + 1, p.f},
{p.x + 1, p.y, p.f},
{p.x - 1, p.y, p.f},
};
return vs[(int)p.f];
}
vpos burst(std::set<node22>& infected, vpos p, int* c) {
auto it = infected.find({p.x, p.y});
bool is_infected = it != infected.end();
// If the current node is infected, it turns to its right. Otherwise, it turns to its left. (Turning is done in-place;
// the current node does not change.)
vpos px = is_infected ? turn_right(p) : turn_left(p);
// If the current node is clean, it becomes infected. Otherwise, it becomes
// cleaned. (This is done after the node is considered for the purposes of changing direction.) The virus carrier
if (!is_infected) {
infected.insert({p.x, p.y});
*c += 1;
} else {
infected.erase(it);
}
// moves forward one node in the direction it is facing.
px = move(px);
return px;
}
static void load(std::set<node22>& is, int r, line_view lv) {
const char* p = lv.line;
int x = 0;
while (*(p + x) != '\n') {
if (*(p + x) == '#') {
node22 n{x - radias, r - radias};
is.insert(n);
}
x++;
}
}
std::pair<int64_t, int64_t> day22(line_view file) {
std::set<node22> infected;
int r{0};
per_line(file, [&r, &infected](line_view lv) {
load(infected, r++, lv);
return true;
});
vpos p{0, 0, f_up};
int t0{0};
for (int i = 0; i < 10000; i++) {
p = burst(infected, p, &t0);
}
// for (auto& n : infected) {
// printf("%d,%d\n", n.x, n.y);
// }
return {t0, 0};
}
} // namespace aoc2017
|