diff --git a/src/core_test/cases/group_union.cc b/src/core_test/cases/group_union.cc index bf9526e..cbcbafa 100644 --- a/src/core_test/cases/group_union.cc +++ b/src/core_test/cases/group_union.cc @@ -4,6 +4,8 @@ #include #include +#include + // TODO: only for debug #include @@ -11,6 +13,83 @@ #include "helper/cases.h" #include "common_code/common_code.h" +using klotski::cases::Group; +using klotski::cases::GroupUnion; + +using klotski::cases::TYPE_ID_LIMIT; +using klotski::cases::ALL_GROUP_NUM; + +TEST(GroupUnion, basic) { + + EXPECT_TRUE(GroupUnion::create(0).has_value()); + EXPECT_EQ(GroupUnion::create(0).value().unwrap(), 0); + EXPECT_FALSE(GroupUnion::create(TYPE_ID_LIMIT).has_value()); + + EXPECT_EQ(GroupUnion::unsafe_create(0).unwrap(), 0); + + for (uint32_t type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) { + auto group_union = GroupUnion::unsafe_create(type_id); + + auto num = group_union.group_num(); + + auto groups = group_union.groups(); + for (auto x : groups) { + EXPECT_EQ(x.type_id(), type_id); + } + // TODO: add EXPECT_IOTA(...) +// auto group_ids = groups | std::ranges::transform([](Group x) { return x.group_id(); }); + std::vector group_ids; + group_ids.reserve(groups.size()); + for (auto x : groups) { + group_ids.emplace_back(x.group_id()); + } + EXPECT_SORTED_AND_UNIQUE(group_ids); + EXPECT_EQ(group_ids[0], 0); + EXPECT_EQ(group_ids[num - 1], num - 1); + EXPECT_EQ(group_ids.size(), num); + + // TODO: test all + EXPECT_TRUE(group_union.group(0).has_value()); + EXPECT_EQ(group_union.group(0).value().type_id(), type_id); + EXPECT_EQ(group_union.group(0).value().group_id(), 0); + + EXPECT_FALSE(group_union.group(num).has_value()); + } + +} + +TEST(GroupUnion, constant) { + EXPECT_EQ(TYPE_ID_LIMIT, 203); + EXPECT_EQ(ALL_GROUP_NUM, 25422); + + // TODO: verify from local builder + + EXPECT_EQ(TYPE_ID_LIMIT, group_union_num()); + +} + +TEST(GroupUnion, size) { + for (uint32_t type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) { + auto &kk = group_union_cases(type_id); + EXPECT_EQ(GroupUnion::unsafe_create(type_id).size(), kk.size()); + } +} + +TEST(GroupUnion, group_num) { + + for (uint32_t type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) { + EXPECT_EQ(GroupUnion::unsafe_create(type_id).group_num(), group_num(type_id)); + + } +} + +TEST(GroupUnion, cases) { + for (uint32_t type_id = 0; type_id < klotski::cases::TYPE_ID_LIMIT; ++type_id) { + auto cases = group_union_cases(type_id); + EXPECT_EQ(cases, klotski::cases::GroupUnion::unsafe_create(type_id).cases().codes()); + } +} + TEST(GroupUnion, demo) { // for (auto i = 0; i < block_nums().size(); ++i) { @@ -54,27 +133,3 @@ TEST(GroupUnion, demo) { } - -TEST(GroupUnion, cases) { - // auto ret = group_union_cases(0); - // - // EXPECT_EQ(ret, klotski::cases::GroupUnion::unsafe_create(0).cases().codes()); - - // group_union_cases(0); - - for (uint32_t type_id = 0; type_id < klotski::cases::TYPE_ID_LIMIT; ++type_id) { - auto cases = group_union_cases(type_id); - EXPECT_EQ(cases, klotski::cases::GroupUnion::unsafe_create(type_id).cases().codes()); - } -} - -TEST(GroupUnion, group) { - - for (uint32_t type_id = 0; type_id < klotski::cases::TYPE_ID_LIMIT; ++type_id) { - auto ret = group_cases(type_id, 0); - } - - // auto ret = group_cases(169, 0); - // std::cout << ret.size() << std::endl; - -} diff --git a/src/core_test/cases/helper/cases.h b/src/core_test/cases/helper/cases.h index 9d6d4f9..be484d6 100644 --- a/src/core_test/cases/helper/cases.h +++ b/src/core_test/cases/helper/cases.h @@ -101,14 +101,16 @@ const std::vector& block_nums(); // ----------------------------------------------------------------------------------------- // -// TODO: get cases with type id (filter from AllCases) +/// Get the type_id upper limit. +uint32_t group_union_num(); -const std::vector& group_union_cases(uint32_t type_id); - -// TODO: get cases with (type id + group id) (cal data from Group rules) +/// Get the group_id upper limit. +uint32_t group_num(uint32_t type_id); -std::vector group_cases(uint32_t type_id, uint32_t group_id); +/// Get cases contained in the specified type_id. +const std::vector& group_union_cases(uint32_t type_id); -// TODO: always return ref of `std::vector` here +/// Get cases contained in the specified type_id and group_id. +const std::vector& group_cases(uint32_t type_id, uint32_t group_id); // ----------------------------------------------------------------------------------------- // diff --git a/src/core_test/cases/helper/group_impl.cc b/src/core_test/cases/helper/group_impl.cc index 2220cfc..b5cfbe3 100644 --- a/src/core_test/cases/helper/group_impl.cc +++ b/src/core_test/cases/helper/group_impl.cc @@ -48,6 +48,13 @@ static std::vector> split_groups(std::vector } +// TODO: static data of `build_all_cases` + +uint32_t group_union_num() { + static auto data = build_all_cases(); + return data.size(); +} + const std::vector& group_union_cases(const uint32_t type_id) { static auto data = build_all_cases(); if (type_id < data.size()) { @@ -56,12 +63,37 @@ const std::vector& group_union_cases(const uint32_t type_id) { std::abort(); } -// TODO: maybe using multi-threads +// TODO: multi-threads builder + +static std::vector>> all_groups_builder() { + + std::vector>> data; + + for (uint32_t type_id = 0; type_id < group_union_num(); ++type_id) { + + data.emplace_back(split_groups(group_union_cases(type_id))); + + } + + return data; + +} + +uint32_t group_num(uint32_t type_id) { + static auto data = all_groups_builder(); + if (type_id < data.size()) { + return data[type_id].size(); + } + std::abort(); +} -std::vector group_cases(uint32_t type_id, uint32_t group_id) { +const std::vector& group_cases(uint32_t type_id, uint32_t group_id) { - auto groups = split_groups(group_union_cases(type_id)); + static auto data = all_groups_builder(); - return groups[group_id]; + if (type_id < data.size() && group_id < data[type_id].size()) { + return data[type_id][group_id]; + } + std::abort(); }