diff options
Diffstat (limited to 'src/2015/day6/aoc.h')
-rw-r--r-- | src/2015/day6/aoc.h | 50 |
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); }); } }; |