diff --git a/src/core_test/CMakeLists.txt b/src/core_test/CMakeLists.txt index ee1eac8..4a7c11f 100644 --- a/src/core_test/CMakeLists.txt +++ b/src/core_test/CMakeLists.txt @@ -13,6 +13,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}) # ------------------------------------------------------------------------------------ # add_library(test_helper + helper/internal/block_num.cc helper/internal/concurrent.cc helper/internal/parallel.cc helper/internal/hash.cc @@ -28,7 +29,6 @@ set(KLSK_TEST_CASES_SRC cases/all_cases.cc cases/group_union.cc cases/group.cc - cases/helper/block_num.cc cases/helper/group_impl.cc ) diff --git a/src/core_test/cases/group_union.cc b/src/core_test/cases/group_union.cc index 1f7038b..77d6d87 100644 --- a/src/core_test/cases/group_union.cc +++ b/src/core_test/cases/group_union.cc @@ -1,16 +1,16 @@ #include +#include #include #include -#include +#include "helper/cases.h" +#include "helper/parallel.h" +#include "helper/block_num.h" #include "group/group.h" -#include "helper/cases.h" #include "common_code/common_code.h" -#include "helper/parallel.h" - using klotski::codec::ShortCode; using klotski::cases::Group; @@ -93,7 +93,7 @@ TEST(GroupUnion, values) { TEST(GroupUnion, type_id) { ShortCode::speed_up(true); COMMON_CODE_PARALLEL({ - auto type_id = to_type_id(cal_block_num(code.unwrap())); + auto type_id = to_type_id(helper::cal_block_num(code.unwrap())); EXPECT_EQ(GroupUnion::from_common_code(code).unwrap(), type_id); EXPECT_EQ(GroupUnion::from_raw_code(code.to_raw_code()).unwrap(), type_id); EXPECT_EQ(GroupUnion::from_short_code(code.to_short_code()).unwrap(), type_id); diff --git a/src/core_test/cases/helper/cases.h b/src/core_test/cases/helper/cases.h index ca3ab9e..f60d530 100644 --- a/src/core_test/cases/helper/cases.h +++ b/src/core_test/cases/helper/cases.h @@ -69,40 +69,6 @@ protected: // ----------------------------------------------------------------------------------------- // -/// The number of blocks in one klotski layout. -struct block_num_t { - int n_1x1; // 4-bit - int n_1x2; // 3-bit - int n_2x1; // 3-bit -}; - -template <> -struct std::hash { - size_t operator()(const block_num_t val) const noexcept { - return (val.n_1x1 << 6) ^ (val.n_1x2 << 3) ^ val.n_2x1; - } -}; - -constexpr bool operator==(const block_num_t &lhs, const block_num_t &rhs) { - return lhs.n_1x1 == rhs.n_1x1 && lhs.n_1x2 == rhs.n_1x2 && lhs.n_2x1 == rhs.n_2x1; -} - -// ----------------------------------------------------------------------------------------- // - -/// Calculate the block number from Range. -block_num_t cal_block_num(uint32_t range); - -/// Calculate type id value from the block number. -uint32_t to_type_id(block_num_t block_num); - -/// Calculate the block number value from type id. -block_num_t to_block_num(uint32_t type_id); - -/// Get all block number combinations without dependencies. -const std::vector& block_nums(); - -// ----------------------------------------------------------------------------------------- // - /// Get the type_id upper limit. uint32_t group_union_num(); diff --git a/src/core_test/cases/helper/group_impl.cc b/src/core_test/cases/helper/group_impl.cc index ef08fb0..325557c 100644 --- a/src/core_test/cases/helper/group_impl.cc +++ b/src/core_test/cases/helper/group_impl.cc @@ -1,5 +1,7 @@ #include "cases.h" +#include "helper/block_num.h" + // TODO: multi-threads builder /// Extend ordered Group from the specified CommonCode seed. @@ -33,9 +35,9 @@ static std::vector> split_groups(std::vector static const std::vector>& group_union_data() { static auto data = [] { std::vector> codes; - codes.resize(block_nums().size()); + codes.resize(helper::block_nums().size()); for (auto code: AllCases::instance().fetch().codes()) { - codes[to_type_id(cal_block_num(code.unwrap()))].emplace_back(code); + codes[to_type_id(helper::cal_block_num(code.unwrap()))].emplace_back(code); } return codes; }(); diff --git a/src/core_test/cases/ranges.cc b/src/core_test/cases/ranges.cc index 75cc82a..fb9ef13 100644 --- a/src/core_test/cases/ranges.cc +++ b/src/core_test/cases/ranges.cc @@ -1,7 +1,9 @@ #include -#include "group/group.h" #include "helper/cases.h" +#include "helper/block_num.h" + +#include "group/group.h" #include "ranges/ranges.h" using klotski::range_reverse; @@ -26,7 +28,7 @@ TEST(Ranges, spawn) { ranges.spawn(n, n_2x1, n_1x1); EXPECT_SORTED_AND_UNIQUE(ranges); // sorted and unique for (const auto range : ranges) { - const auto [val_1x1, val_1x2, val_2x1] = cal_block_num(range); + const auto [val_1x1, val_1x2, val_2x1] = helper::cal_block_num(range); EXPECT_EQ(val_1x1, n_1x1); EXPECT_EQ(val_2x1, n_2x1); EXPECT_EQ(val_1x2 + val_2x1, n); // verify block nums diff --git a/src/core_test/helper/block_num.h b/src/core_test/helper/block_num.h new file mode 100644 index 0000000..e726229 --- /dev/null +++ b/src/core_test/helper/block_num.h @@ -0,0 +1,48 @@ +#pragma once + +#include + +// ----------------------------------------------------------------------------------------- // + +namespace helper { + +struct block_num_t { + int n_1x1; // 4-bit + int n_1x2; // 3-bit + int n_2x1; // 3-bit +}; + +constexpr bool operator==(const block_num_t &lhs, const block_num_t &rhs) { + return lhs.n_1x1 == rhs.n_1x1 + && lhs.n_1x2 == rhs.n_1x2 + && lhs.n_2x1 == rhs.n_2x1; +} + +/// Calculate the block number from Range. +block_num_t cal_block_num(uint32_t range); + +/// Calculate type id value from the block number. +uint32_t to_type_id(block_num_t block_num); + +/// Calculate the block number value from type id. +block_num_t to_block_num(uint32_t type_id); + +/// Get all block number combinations without dependencies. +const std::vector& block_nums(); + +} // namespace helper + +// ----------------------------------------------------------------------------------------- // + +namespace std { + +template <> +struct std::hash { + size_t operator()(const helper::block_num_t val) const noexcept { + return (val.n_1x1 << 6) ^ (val.n_1x2 << 3) ^ val.n_2x1; + } +}; + +} // namespace std + +// ----------------------------------------------------------------------------------------- // diff --git a/src/core_test/cases/helper/block_num.cc b/src/core_test/helper/internal/block_num.cc similarity index 76% rename from src/core_test/cases/helper/block_num.cc rename to src/core_test/helper/internal/block_num.cc index d68d29d..fb38320 100644 --- a/src/core_test/cases/helper/block_num.cc +++ b/src/core_test/helper/internal/block_num.cc @@ -1,9 +1,12 @@ #include #include +#include #include -#include "cases.h" +#include "ranges/ranges.h" +#include "helper/block_num.h" +using helper::block_num_t; using klotski::range_reverse; /// Build the sequence list of all block numbers. @@ -33,18 +36,18 @@ static std::vector build_block_nums() { /// Build the mapping table from block_num to type_id. static std::unordered_map build_type_id_map() { std::unordered_map ids; - for (uint64_t i = 0; i < block_nums().size(); ++i) { - ids.emplace(block_nums()[i], i); // TODO: using `std::views::enumerate` + for (uint64_t i = 0; i < helper::block_nums().size(); ++i) { + ids.emplace(helper::block_nums()[i], i); // TODO: using `std::views::enumerate` } return ids; } -const std::vector& block_nums() { +const std::vector& helper::block_nums() { static auto data = build_block_nums(); return data; } -block_num_t cal_block_num(uint32_t range) { +block_num_t helper::cal_block_num(uint32_t range) { block_num_t result {}; for (range = range_reverse(range); range; range >>= 2) { switch (range & 0b11) { @@ -63,14 +66,14 @@ block_num_t cal_block_num(uint32_t range) { return result; } -block_num_t to_block_num(const uint32_t type_id) { - if (type_id < block_nums().size()) { - return block_nums()[type_id]; +block_num_t helper::to_block_num(const uint32_t type_id) { + if (type_id < helper::block_nums().size()) { + return helper::block_nums()[type_id]; } std::abort(); } -uint32_t to_type_id(const block_num_t block_num) { +uint32_t helper::to_type_id(const block_num_t block_num) { static auto data = build_type_id_map(); if (const auto match = data.find(block_num); match != data.end()) { return match->second;