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
|
#pragma once
#include "common.h"
namespace aoc2015 {
struct neolight {
constexpr static size_t size = 100 * 100;
uint8_t bs[size] = {0};
int count() const noexcept {
int d{0};
for (auto i : bs) {
if (i > 0) {
d += 1;
}
}
return d;
}
void turn(int x, int y, int v) { bs[y * 100 + x] = v; }
bool on(int x, int y) const noexcept {
if (x < 0 || y < 0 || x > 99 || y > 99) {
return false;
}
return is_corner(x, y) ? true : bs[y * 100 + x] > 0;
}
bool is_corner(int x, int y) const noexcept {
bool b1 = x == 0 && y == 0;
bool b2 = x == 0 && y == 99;
bool b3 = x == 99 && y == 0;
bool b4 = x == 99 && y == 99;
return b1 || b2 || b3 || b4;
}
int count(int x, int y) const noexcept {
int d{0};
for (int i = -1; i < 2; i++) {
for (int j = -1; j < 2; j++) {
if (!(i == 0 && j == 0)) {
d += on(x + i, y + j) ? 1 : 0;
}
}
}
return d;
}
void turn_on_corners() {
struct _ {
int x;
int y;
} corners[] = {{0, 0}, {0, 99}, {99, 0}, {99, 99}};
for (auto c : corners) {
turn(c.x, c.y, 1);
}
}
};
struct yard {
neolight* lights = new neolight;
void transform(int x, int y, neolight* g, neolight* n) {
if (g->on(x, y)) {
int v = 0;
int neighbors = g->count(x, y);
if (neighbors == 2 || neighbors == 3) {
v = 1;
}
n->turn(x, y, v);
} else {
int v = 0;
int neighbors = g->count(x, y);
if (neighbors == 3) {
v = 1;
}
n->turn(x, y, v);
}
n->turn_on_corners();
}
neolight* next(neolight* g) {
neolight* n = new neolight;
for (int x = 0; x < 100; x++) {
for (int y = 0; y < 100; y++) {
transform(x, y, g, n);
}
}
return n;
}
void turns(int i) {
while (i-- > 0) {
lights = next(lights);
}
}
int count() { return lights != nullptr ? lights->count() : 0; }
void parse(line_view file) {
int x = 0;
int y = 0;
const char* p = file.line;
while (p != file.line + file.length) {
if (*p == '#') {
lights->turn(x++, y, 1);
}
if (*p == '.') {
lights->turn(x++, y, 0);
}
if (*p == '\n') {
x = 0;
y += 1;
}
p++;
}
lights->turn_on_corners();
}
};
int day18(line_view, int);
} // namespace aoc2015
|