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
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
)

10
src/core_test/cases/group_union.cc

@ -1,16 +1,16 @@
#include <gtest/gtest.h>
#include <ranges>
#include <cstdint>
#include <algorithm>
#include <ranges>
#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);

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.
uint32_t group_union_num();

6
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<std::vector<CommonCode>> split_groups(std::vector<CommonCode>
static const std::vector<std::vector<CommonCode>>& group_union_data() {
static auto data = [] {
std::vector<std::vector<CommonCode>> 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;
}();

6
src/core_test/cases/ranges.cc

@ -1,7 +1,9 @@
#include <gtest/gtest.h>
#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

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 <vector>
#include <algorithm>
#include <unordered_map>
#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<block_num_t> build_block_nums() {
/// Build the mapping table from block_num to type_id.
static std::unordered_map<block_num_t, uint32_t> build_type_id_map() {
std::unordered_map<block_num_t, uint32_t> 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_num_t>& block_nums() {
const std::vector<block_num_t>& 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;
Loading…
Cancel
Save