Browse Source

feat: block_num test helper

legacy
Dnomd343 3 months ago
parent
commit
1fe4e67a84
  1. 2
      src/core_test/CMakeLists.txt
  2. 10
      src/core_test/cases/group_union.cc
  3. 34
      src/core_test/cases/helper/cases.h
  4. 6
      src/core_test/cases/helper/group_impl.cc
  5. 6
      src/core_test/cases/ranges.cc
  6. 48
      src/core_test/helper/block_num.h
  7. 21
      src/core_test/helper/internal/block_num.cc

2
src/core_test/CMakeLists.txt

@ -13,6 +13,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR})
# ------------------------------------------------------------------------------------ # # ------------------------------------------------------------------------------------ #
add_library(test_helper add_library(test_helper
helper/internal/block_num.cc
helper/internal/concurrent.cc helper/internal/concurrent.cc
helper/internal/parallel.cc helper/internal/parallel.cc
helper/internal/hash.cc helper/internal/hash.cc
@ -28,7 +29,6 @@ set(KLSK_TEST_CASES_SRC
cases/all_cases.cc cases/all_cases.cc
cases/group_union.cc cases/group_union.cc
cases/group.cc cases/group.cc
cases/helper/block_num.cc
cases/helper/group_impl.cc cases/helper/group_impl.cc
) )

10
src/core_test/cases/group_union.cc

@ -1,16 +1,16 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <ranges>
#include <cstdint> #include <cstdint>
#include <algorithm> #include <algorithm>
#include <ranges> #include "helper/cases.h"
#include "helper/parallel.h"
#include "helper/block_num.h"
#include "group/group.h" #include "group/group.h"
#include "helper/cases.h"
#include "common_code/common_code.h" #include "common_code/common_code.h"
#include "helper/parallel.h"
using klotski::codec::ShortCode; using klotski::codec::ShortCode;
using klotski::cases::Group; using klotski::cases::Group;
@ -93,7 +93,7 @@ TEST(GroupUnion, values) {
TEST(GroupUnion, type_id) { TEST(GroupUnion, type_id) {
ShortCode::speed_up(true); ShortCode::speed_up(true);
COMMON_CODE_PARALLEL({ 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_common_code(code).unwrap(), type_id);
EXPECT_EQ(GroupUnion::from_raw_code(code.to_raw_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); EXPECT_EQ(GroupUnion::from_short_code(code.to_short_code()).unwrap(), type_id);

34
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<block_num_t> {
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_num_t>& block_nums();
// ----------------------------------------------------------------------------------------- //
/// Get the type_id upper limit. /// Get the type_id upper limit.
uint32_t group_union_num(); uint32_t group_union_num();

6
src/core_test/cases/helper/group_impl.cc

@ -1,5 +1,7 @@
#include "cases.h" #include "cases.h"
#include "helper/block_num.h"
// TODO: multi-threads builder // TODO: multi-threads builder
/// Extend ordered Group from the specified CommonCode seed. /// Extend ordered Group from the specified CommonCode seed.
@ -33,9 +35,9 @@ static std::vector<std::vector<CommonCode>> split_groups(std::vector<CommonCode>
static const std::vector<std::vector<CommonCode>>& group_union_data() { static const std::vector<std::vector<CommonCode>>& group_union_data() {
static auto data = [] { static auto data = [] {
std::vector<std::vector<CommonCode>> codes; std::vector<std::vector<CommonCode>> codes;
codes.resize(block_nums().size()); codes.resize(helper::block_nums().size());
for (auto code: AllCases::instance().fetch().codes()) { 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; return codes;
}(); }();

6
src/core_test/cases/ranges.cc

@ -1,7 +1,9 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "group/group.h"
#include "helper/cases.h" #include "helper/cases.h"
#include "helper/block_num.h"
#include "group/group.h"
#include "ranges/ranges.h" #include "ranges/ranges.h"
using klotski::range_reverse; using klotski::range_reverse;
@ -26,7 +28,7 @@ TEST(Ranges, spawn) {
ranges.spawn(n, n_2x1, n_1x1); ranges.spawn(n, n_2x1, n_1x1);
EXPECT_SORTED_AND_UNIQUE(ranges); // sorted and unique EXPECT_SORTED_AND_UNIQUE(ranges); // sorted and unique
for (const auto range : ranges) { 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_1x1, n_1x1);
EXPECT_EQ(val_2x1, n_2x1); EXPECT_EQ(val_2x1, n_2x1);
EXPECT_EQ(val_1x2 + val_2x1, n); // verify block nums EXPECT_EQ(val_1x2 + val_2x1, n); // verify block nums

48
src/core_test/helper/block_num.h

@ -0,0 +1,48 @@
#pragma once
#include <cstdint>
// ----------------------------------------------------------------------------------------- //
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_num_t>& block_nums();
} // namespace helper
// ----------------------------------------------------------------------------------------- //
namespace std {
template <>
struct std::hash<helper::block_num_t> {
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
// ----------------------------------------------------------------------------------------- //

21
src/core_test/cases/helper/block_num.cc → src/core_test/helper/internal/block_num.cc

@ -1,9 +1,12 @@
#include <ranges> #include <ranges>
#include <vector> #include <vector>
#include <algorithm>
#include <unordered_map> #include <unordered_map>
#include "cases.h" #include "ranges/ranges.h"
#include "helper/block_num.h"
using helper::block_num_t;
using klotski::range_reverse; using klotski::range_reverse;
/// Build the sequence list of all block numbers. /// Build the sequence list of all block numbers.
@ -33,18 +36,18 @@ static std::vector<block_num_t> build_block_nums() {
/// Build the mapping table from block_num to type_id. /// Build the mapping table from block_num to type_id.
static std::unordered_map<block_num_t, uint32_t> build_type_id_map() { static std::unordered_map<block_num_t, uint32_t> build_type_id_map() {
std::unordered_map<block_num_t, uint32_t> ids; std::unordered_map<block_num_t, uint32_t> ids;
for (uint64_t i = 0; i < block_nums().size(); ++i) { for (uint64_t i = 0; i < helper::block_nums().size(); ++i) {
ids.emplace(block_nums()[i], i); // TODO: using `std::views::enumerate` ids.emplace(helper::block_nums()[i], i); // TODO: using `std::views::enumerate`
} }
return ids; return ids;
} }
const std::vector<block_num_t>& block_nums() { const std::vector<block_num_t>& helper::block_nums() {
static auto data = build_block_nums(); static auto data = build_block_nums();
return data; 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 {}; block_num_t result {};
for (range = range_reverse(range); range; range >>= 2) { for (range = range_reverse(range); range; range >>= 2) {
switch (range & 0b11) { switch (range & 0b11) {
@ -63,14 +66,14 @@ block_num_t cal_block_num(uint32_t range) {
return result; return result;
} }
block_num_t to_block_num(const uint32_t type_id) { block_num_t helper::to_block_num(const uint32_t type_id) {
if (type_id < block_nums().size()) { if (type_id < helper::block_nums().size()) {
return block_nums()[type_id]; return helper::block_nums()[type_id];
} }
std::abort(); 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(); static auto data = build_type_id_map();
if (const auto match = data.find(block_num); match != data.end()) { if (const auto match = data.find(block_num); match != data.end()) {
return match->second; return match->second;
Loading…
Cancel
Save