diff options
author | Kai WU <kaiwu2004@gmail.com> | 2022-03-16 22:44:44 +0800 |
---|---|---|
committer | Kai WU <kaiwu2004@gmail.com> | 2022-03-16 22:44:44 +0800 |
commit | 4747911566e69b1d95e88bb5955ffbeddfae6a08 (patch) | |
tree | 37342293bc87165fafbfb385d8bdd49328b748e4 | |
parent | 02b94aafe0c11962b24d0d6f70794fb630e3ceca (diff) | |
download | advent-of-code-4747911566e69b1d95e88bb5955ffbeddfae6a08.tar.gz advent-of-code-4747911566e69b1d95e88bb5955ffbeddfae6a08.zip |
1024
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/2015/day6/aoc.h | 50 | ||||
-rw-r--r-- | test/test_2015.cpp | 6 |
3 files changed, 49 insertions, 9 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 4782b07..f0fbd5e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.8) project(advent-of-code LANGUAGES CXX) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wall -Wextra -pedantic -Wno-unused-parameter") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O3 -Wall -Wextra -pedantic -Wno-unused-parameter") set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_EXTENSIONS Off) 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); }); } }; diff --git a/test/test_2015.cpp b/test/test_2015.cpp index 5a55d13..a6bb135 100644 --- a/test/test_2015.cpp +++ b/test/test_2015.cpp @@ -72,3 +72,9 @@ TEST_CASE("Doesn't He Have Intern-Elves For This?", "[day5]") { REQUIRE(p.first == 255); REQUIRE(p.second == 55); } + +TEST_CASE("Probably a Fire Hazard", "[day6]") { + aoc2015::grid<1024> grid; + grid.turn_on({0,0}, {0,999}); + REQUIRE(grid.count() == 1000); +} |