aboutsummaryrefslogtreecommitdiff
path: root/src/2015/day6/aoc.h
diff options
context:
space:
mode:
authorKai WU <kaiwu2004@gmail.com>2022-03-16 22:44:44 +0800
committerKai WU <kaiwu2004@gmail.com>2022-03-16 22:44:44 +0800
commit4747911566e69b1d95e88bb5955ffbeddfae6a08 (patch)
tree37342293bc87165fafbfb385d8bdd49328b748e4 /src/2015/day6/aoc.h
parent02b94aafe0c11962b24d0d6f70794fb630e3ceca (diff)
downloadadvent-of-code-4747911566e69b1d95e88bb5955ffbeddfae6a08.tar.gz
advent-of-code-4747911566e69b1d95e88bb5955ffbeddfae6a08.zip
1024
Diffstat (limited to 'src/2015/day6/aoc.h')
-rw-r--r--src/2015/day6/aoc.h50
1 files changed, 42 insertions, 8 deletions
diff --git a/src/2015/day6/aoc.h b/src/2015/day6/aoc.h
index c178277..b68ef18 100644
--- a/src/2015/day6/aoc.h
+++ b/src/2015/day6/aoc.h
@@ -4,36 +4,70 @@
namespace aoc2015 {
+template <size_t N>
struct grid {
- uint8_t* pool;
+ static_assert(N > 0 && ((N & (N - 1)) == 0), "N must be power of 2");
+ constexpr static size_t size = N * N / 64;
+
+ uint64_t pool[size] = {0};
struct unit {
int x;
int y;
};
- grid(int x, int y) {
- pool = (uint8_t*)malloc(x * y);
- memset(pool, 0x0, x * y);
+ void set(int x, int y) {
+ uint64_t p = x * N + y;
+ uint64_t r = p >> 6;
+ uint64_t c = p & 63;
+ uint64_t& byte = pool[r];
+ uint64_t mask = 1 << c;
+ byte |= mask;
+ }
+
+ void reset(int x, int y) {
+ uint64_t p = x * N + y;
+ uint64_t r = p >> 6;
+ uint64_t c = p & 63;
+ uint64_t& byte = pool[r];
+ uint64_t mask = ~(1 << c);
+ byte &= mask;
+ }
+
+ void toggle(int x, int y) {
+ uint64_t p = x * N + y;
+ uint64_t r = p >> 6;
+ uint64_t c = p & 63;
+ uint64_t& byte = pool[r];
+ uint64_t mask = 1 << c;
+ byte ^= mask;
+ }
+
+ int count() const noexcept {
+ int total = 0;
+ for (uint64_t i : pool) {
+ total += __builtin_popcountll(i);
+ }
+ return total;
}
template <typename F, typename... Args>
void traverse(unit u1, unit u2, F&& f, Args&&... args) {
for (int i = u1.x; i <= u2.x; i++) {
for (int j = u1.y; j <= u2.y; j++) {
- f(pool[i * j], std::forward<Args>(args)...);
+ f(i, j, std::forward<Args>(args)...);
}
}
}
void turn_on(unit u1, unit u2) {
- traverse(u1, u2, [](uint8_t& u) { u = 1; });
+ traverse(u1, u2, [this](int i, int j) { set(i, j); });
}
void turn_off(unit u1, unit u2) {
- traverse(u1, u2, [](uint8_t& u) { u = 0; });
+ traverse(u1, u2, [this](int i, int j) { reset(i, j); });
}
void toggle(unit u1, unit u2) {
- traverse(u1, u2, [](uint8_t& u) { u = !u; });
+ traverse(u1, u2, [this](int i, int j) { toggle(i, j); });
}
};