diff --git a/2017/06.cpp b/2017/06.cpp new file mode 100644 index 0000000..e868b3a --- /dev/null +++ b/2017/06.cpp @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +namespace { + +template +using Banks = std::array; + +auto Parse(std::istream & in) -> Banks<16> { + Banks<16> result; + for (auto & x : result) { + if (!(in >> x)) { + throw std::runtime_error{"bad input"}; + } + } + + return result; +} + +template +auto Redistribute(Banks & banks) { + auto it = std::max_element(banks.begin(), banks.end()); + auto val = *it; + *it++ = 0; + for (; val > 0; val--) { + if (it == banks.end()) it = banks.begin(); + (*it++)++; + } +} + +template +auto CycleSearch(Banks & banks) +-> std::pair +{ + std::map, std::size_t> seen {{banks, 0}}; + std::size_t n = 0; + for(;;) { + Redistribute(banks); + n++; + auto [it, success] = seen.try_emplace(banks, n); + if (!success) { + return {n, n - it->second}; + } + } +} + +} // namespace + +TEST_SUITE("2017-06 examples") { + TEST_CASE("example") { + Banks<4> banks {0, 2, 7, 0}; + + SUBCASE("single step") { + Redistribute(banks); + REQUIRE(banks == Banks<4>{2, 4, 1, 2}); + Redistribute(banks); + REQUIRE(banks == Banks<4>{3, 1, 2, 3}); + Redistribute(banks); + REQUIRE(banks == Banks<4>{0, 2, 3, 4}); + Redistribute(banks); + REQUIRE(banks == Banks<4>{1, 3, 4, 1}); + Redistribute(banks); + REQUIRE(banks == Banks<4>{2, 4, 1, 2}); + } + + SUBCASE("full example") { + auto [p1,p2] = CycleSearch(banks); + CHECK(p1 == 5); + CHECK(p2 == 4); + } + } +} + +auto main(int argc, char** argv) -> int { + auto input = Parse(*aocpp::Startup(argc, argv)); + auto answer = CycleSearch(input); + std::cout << "Part 1: " << answer.first << std::endl; + std::cout << "Part 2: " << answer.second << std::endl; +} \ No newline at end of file diff --git a/2017/14.cpp b/2017/14.cpp index 7e2b427..c97cc6d 100644 --- a/2017/14.cpp +++ b/2017/14.cpp @@ -88,11 +88,13 @@ auto CountComponents(Grid const& grid) -> std::uint16_t { } // namespace -TEST_CASE("documented example") { +TEST_SUITE("2017-14 examples") { +TEST_CASE("flqrgnkx") { auto rows = MakeRows("flqrgnkx"); CHECK(CountBits(rows) == 8108); CHECK(CountComponents(rows) == 1242); } +} auto main(int argc, char** argv) -> int { std::string input; diff --git a/2017/CMakeLists.txt b/2017/CMakeLists.txt index 50c7b8c..8bd0168 100644 --- a/2017/CMakeLists.txt +++ b/2017/CMakeLists.txt @@ -1,3 +1,6 @@ +add_executable(2017_06 06.cpp) +target_link_libraries(2017_06 aocpp) + add_executable(2017_10 10.cpp) target_link_libraries(2017_10 aocpp knothash) diff --git a/knothash/src/knothash.cpp b/knothash/src/knothash.cpp index ac9193d..57d16a0 100644 --- a/knothash/src/knothash.cpp +++ b/knothash/src/knothash.cpp @@ -36,7 +36,7 @@ auto render(std::array const& hash) -> std::string { return out.str(); } -TEST_SUITE("knot hash") { +TEST_SUITE("knothash library") { TEST_CASE("reverser") { std::array v {0,1,2,3,4,5,6,7,8}; @@ -44,13 +44,13 @@ TEST_CASE("reverser") { SUBCASE("more left") { std::array expect {1,0,8,7,4,5,6,3,2}; reverser(v, 7, 6); - REQUIRE(v == expect); + CHECK(v == expect); } SUBCASE("more right") { std::array expect {6,5,2,3,4,1,0,8,7}; reverser(v, 5, 6); - REQUIRE(v == expect); + CHECK(v == expect); } SUBCASE("middle") {