From c6a83a9aed3dd7c609f0a7c479230f277caab4ee Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Fri, 14 Apr 2023 20:26:55 +0800 Subject: [PATCH] update: enhance groups build --- src/klotski_core/ffi/tmain.cc | 11 ++++++-- src/klotski_core/group/build_cases.cc | 37 +++++++++++++++------------ src/klotski_core/group/group.h | 18 ++++++++----- test/group/build_cases.cc | 4 +-- 4 files changed, 42 insertions(+), 28 deletions(-) diff --git a/src/klotski_core/ffi/tmain.cc b/src/klotski_core/ffi/tmain.cc index bfb6550..8dc444f 100644 --- a/src/klotski_core/ffi/tmain.cc +++ b/src/klotski_core/ffi/tmain.cc @@ -19,6 +19,7 @@ #include "group.h" using klotski::Group; +using klotski::TypeId; using klotski::AllCases; using klotski::RawCode; @@ -33,10 +34,16 @@ using klotski::TYPE_ID_LIMIT; void tmain() { // printf("tmain start\n"); + auto start = clock(); + // Group::build_group(123, 233); - auto seed = Group::group_seed(123, 233); - std::cout << seed << std::endl; + Group::build_groups(TypeId(123)); + + std::cerr << (clock() - start) * 1000 / CLOCKS_PER_SEC << "ms" << std::endl; + +// auto seed = Group::group_seed(123, 233); +// std::cout << seed << std::endl; // Group::group_info(CommonCode(0x1A9BF0C00)); diff --git a/src/klotski_core/group/build_cases.cc b/src/klotski_core/group/build_cases.cc index e844441..ed72b1f 100644 --- a/src/klotski_core/group/build_cases.cc +++ b/src/klotski_core/group/build_cases.cc @@ -5,6 +5,7 @@ #include "type_id.h" #include "common_code.h" #include "absl/container/flat_hash_map.h" +#include "absl/container/btree_set.h" #include "type_id.h" #include "group_seeds.h" @@ -14,8 +15,8 @@ namespace klotski { using Common::check_range; using Common::range_reverse; -std::vector Group::all_cases(uint32_t type_id) { - auto tmp = TypeId(type_id).block_num(); +std::vector Group::all_cases(const TypeId &type_id) { + auto tmp = type_id.block_num(); std::vector ranges; // basic ranges of type_id BasicRanges::generate(ranges, { // generate target ranges .n1 = 16 - tmp.n_1x1 - (tmp.n_1x2 + tmp.n_2x1) * 2, /// space -> 00 @@ -28,7 +29,7 @@ std::vector Group::all_cases(uint32_t type_id) { } std::vector all_cases; - all_cases.reserve(TYPE_ID_SIZE[type_id]); + all_cases.reserve(TYPE_ID_SIZE[type_id.unwrap()]); for (uint64_t head = 0; head < 15; ++head) { // address of 2x2 block /// head -> 0/1/2 / 4/5/6 / 8/9/10 / 12/13/14 if ((head & 0b11) == 0b11) { @@ -46,12 +47,12 @@ std::vector Group::all_cases(uint32_t type_id) { return all_cases; } -std::vector Group::group_cases(const RawCode &raw_code) { +absl::flat_hash_map expansion(const RawCode &entry) { std::queue cache; absl::flat_hash_map cases; // - cases.reserve(max_group_size(raw_code)); - cases.emplace(raw_code.unwrap(), 0); // without mask - cache.emplace(raw_code.unwrap()); + cases.reserve(Group::group_max_size(entry)); + cases.emplace(entry.unwrap(), 0); // without mask + cache.emplace(entry.unwrap()); auto core = Core( [&cache, &cases](auto &&code, auto &&mask) { // callback function @@ -68,7 +69,11 @@ std::vector Group::group_cases(const RawCode &raw_code) { core.next_cases(cache.front(), cases.find(cache.front())->second); cache.pop(); // case dequeue } + return cases; +} +std::vector Group::group_cases(const RawCode &raw_code) { + auto cases = expansion(raw_code); auto result = std::vector(); result.reserve(cases.size()); for (auto &&tmp : cases) { // export group cases @@ -77,7 +82,6 @@ std::vector Group::group_cases(const RawCode &raw_code) { return result; } -// TODO: test this function std::vector Group::group_cases(const CommonCode &common_code) { return group_cases(RawCode::from_common_code(common_code)); } @@ -121,9 +125,10 @@ std::vector Group::build_group(uint32_t type_id, uint32_t group_id) return {}; // group_id out of range } -std::vector> Group::build_groups(uint32_t type_id) { +std::vector> Group::build_groups(const TypeId &type_id) { auto all_cases = Group::all_cases(type_id); std::vector> groups; + auto min = std::min_element(all_cases.begin(), all_cases.end()); // search min CommonCode auto first_group = group_cases(min->to_raw_code()); // expand the first group groups.emplace_back(first_group.begin(), first_group.end()); @@ -131,17 +136,15 @@ std::vector> Group::build_groups(uint32_t type_id) { return groups; } - std::set cases(all_cases.begin(), all_cases.end()); - for (auto &&tmp : groups[0]) { + absl::btree_set cases(all_cases.begin(), all_cases.end()); + for (auto &&tmp : *groups.begin()) { cases.erase(tmp); // remove elements in first group } while (!cases.empty()) { - groups.emplace_back(); // create empty vector - auto current_group = groups.end() - 1; // insert into latest - for (auto &&tmp : group_cases(cases.begin()->to_raw_code())) { - auto common_code = tmp.to_common_code(); - current_group->emplace_back(common_code); // insert into current group - cases.erase(common_code); // remove from global union + auto group = group_cases(cases.begin()->to_raw_code()); + groups.emplace_back(group.begin(), group.end()); // release new group + for (auto &&tmp : *(groups.end() - 1)) { + cases.erase(tmp); // remove selected cases } } diff --git a/src/klotski_core/group/group.h b/src/klotski_core/group/group.h index e7666e0..1473672 100644 --- a/src/klotski_core/group/group.h +++ b/src/klotski_core/group/group.h @@ -89,14 +89,14 @@ public: /// --------------------------------- cases expansion --------------------------------- /// Search for all cases of the specified type_id. - static std::vector all_cases(uint32_t type_id); + static std::vector all_cases(const TypeId &type_id); /// Search for all derivatives that a case can produce. static std::vector group_cases(const RawCode &raw_code); static std::vector group_cases(const CommonCode &common_code); /// Calculate all groups in the specified type_id. - static std::vector> build_groups(uint32_t type_id); + static std::vector> build_groups(const TypeId &type_id); /// Calculate the specified group using type_id and group_id. static std::vector build_group(uint32_t type_id, uint32_t group_id); @@ -124,13 +124,17 @@ public: // TODO: update max_group_size in TYPE_ID_MAX_GROUP -// static uint32_t max_group_size(uint32_t type_id); - - static uint32_t max_group_size(const RawCode &raw_code) { + static uint32_t group_max_size(const TypeId &type_id) { return 65535 * 8; - }; + } + + static uint32_t group_max_size(const RawCode &raw_code) { + return group_max_size(TypeId(raw_code)); + } -// static uint32_t max_group_size(const CommonCode &common_code); + static uint32_t group_max_size(const CommonCode &common_code) { + return group_max_size(TypeId(common_code)); + } // TODO: group_num diff --git a/test/group/build_cases.cc b/test/group/build_cases.cc index cfd58ae..83cbbcd 100644 --- a/test/group/build_cases.cc +++ b/test/group/build_cases.cc @@ -28,7 +28,7 @@ const char GROUP_INFO_MD5[] = "976bf22530085210e68a6a4e67053506"; TEST(Group, all_cases) { std::vector> all_cases; for (uint32_t type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) { - all_cases.emplace_back(Group::all_cases(type_id)); // build test data + all_cases.emplace_back(Group::all_cases(TypeId(type_id))); // build test data } std::vector combine; @@ -99,7 +99,7 @@ TEST(Group, build_groups) { for (uint16_t type_id = 0; type_id < klotski::TYPE_ID_LIMIT; ++type_id) { std::vector group_sizes; std::vector group_seeds; - auto groups = Group::build_groups(type_id); + auto groups = Group::build_groups(TypeId(type_id)); group_sizes.reserve(groups.size()); group_seeds.reserve(groups.size());