From cbc88e907bfbed1c1fb08b2dfeaabaf9b9a02770 Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sat, 15 Apr 2023 10:53:50 +0800 Subject: [PATCH] update: enhance group cases build --- src/klotski_core/group/build_cases.cc | 113 ++++---------------------- src/klotski_core/group/group.h | 16 ++-- src/klotski_core/group/seeds.cc | 40 +++------ 3 files changed, 41 insertions(+), 128 deletions(-) diff --git a/src/klotski_core/group/build_cases.cc b/src/klotski_core/group/build_cases.cc index 3102dc4..2488189 100644 --- a/src/klotski_core/group/build_cases.cc +++ b/src/klotski_core/group/build_cases.cc @@ -7,17 +7,25 @@ #include "absl/container/flat_hash_map.h" #include "absl/container/btree_set.h" -#include "type_id.h" -#include "group_seeds.h" - namespace klotski { using Common::check_range; using Common::range_reverse; +std::vector Group::group_cases(const CommonCode &common_code) { + return group_cases(common_code.to_raw_code()); +} + +std::vector Group::build_group(const GroupId &group_id) { + auto cases = group_cases(group_seed(group_id)); + return {cases.begin(), cases.end()}; +} + std::vector Group::all_cases(const TypeId &type_id) { - auto tmp = type_id.block_num(); std::vector ranges; // basic ranges of type_id + ranges.reserve(TYPE_ID_SIZE[type_id.unwrap()]); // over-allocation + + auto tmp = type_id.block_num(); BasicRanges::generate(ranges, { // generate target ranges .n1 = 16 - tmp.n_1x1 - (tmp.n_1x2 + tmp.n_2x1) * 2, /// space -> 00 .n2 = tmp.n_1x2, /// 1x2 -> 01 @@ -47,10 +55,6 @@ std::vector Group::all_cases(const TypeId &type_id) { return all_cases; } -//absl::flat_hash_map expansion(const RawCode &entry) { -// -//} - std::vector Group::group_cases(const RawCode &raw_code) { std::queue cache; absl::flat_hash_map cases; // @@ -74,7 +78,7 @@ std::vector Group::group_cases(const RawCode &raw_code) { cache.pop(); // case dequeue } - auto result = std::vector(); + std::vector result; result.reserve(cases.size()); for (auto &&tmp : cases) { // export group cases result.emplace_back(RawCode::unsafe_create(tmp.first)); @@ -82,87 +86,6 @@ std::vector Group::group_cases(const RawCode &raw_code) { return result; } -std::vector Group::group_cases(const CommonCode &common_code) { - return group_cases(RawCode::from_common_code(common_code)); -} - -CommonCode Group::group_seed(const RawCode &raw_code) { - -// auto t = expansion(raw_code); -// -// auto k = t.begin(); -// -// auto cmp = [](const std::pair &p1, const std::pair &p2) { -// return RawCode::unsafe_create(p1.first).to_common_code() < RawCode::unsafe_create(p2.first).to_common_code(); -// }; -// -// return std::min_element(t.begin(), t.end(), cmp)->first; - - - auto cases = group_cases(raw_code); - std::vector group(cases.begin(), cases.end()); - - return *std::min_element(group.begin(), group.end()); - - -// std::vector group; -// -// for (auto &&tmp : expansion(raw_code)) { -// group.emplace_back(RawCode::unsafe_create(tmp.first).to_common_code()); -// } -// -// return *std::min_element(group.begin(), group.end()); -} - -CommonCode Group::group_seed(const CommonCode &common_code) { - - return group_seed(common_code.to_raw_code()); - -} - -// TODO: refactor build_group -> using GROUP_SEEDS -std::vector Group::build_group(const GroupId &group_id) { - -// auto offset = TYPE_ID_OFFSET[type_id]; -// -// std::cout << "size: " << TYPE_ID_GROUP_NUM[type_id] << std::endl; -// -// auto k = GROUP_SEEDS_INDEX[offset + group_id]; -// -// std::cout << "tmp index: " << k << std::endl; -// -// auto r = k + offset; -// -// std::cout << "real index: " << r << std::endl; -// -// auto seed = CommonCode(GROUP_SEEDS[r]); -// -// std::cout << "seed: " << seed << std::endl; -// -// std::cout << RawCode(seed) << std::endl; - - auto seed = group_seed(group_id); - - return group_cases(seed); - - -// uint32_t group_num = 0; -// auto all_cases = Group::all_cases(type_id); // load all cases of type_id -// std::set cases(all_cases.begin(), all_cases.end()); -// -// while (!cases.empty()) { -// if (group_id == group_num) { // found target group -// auto group = group_cases(cases.begin()->to_raw_code()); -// return {group.begin(), group.end()}; -// } -// for (auto &&tmp : group_cases(cases.begin()->to_raw_code())) { -// cases.erase(tmp.to_common_code()); // remove from global union -// } -// ++group_num; -// } - return {}; // group_id out of range -} - std::vector> Group::build_groups(const TypeId &type_id) { auto all_cases = Group::all_cases(type_id); std::vector> groups; @@ -170,13 +93,13 @@ std::vector> Group::build_groups(const TypeId &type_id) 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()); - if (first_group.size() == all_cases.size()) { // only contains one group - return groups; + if (first_group.size() == all_cases.size()) { + return groups; // only contains one group } absl::btree_set cases(all_cases.begin(), all_cases.end()); for (auto &&tmp : *groups.begin()) { - cases.erase(tmp); // remove elements in first group + cases.erase(tmp); // remove elements from first group } while (!cases.empty()) { auto group = group_cases(cases.begin()->to_raw_code()); @@ -186,10 +109,10 @@ std::vector> Group::build_groups(const TypeId &type_id) } } - auto compare_func = [](const std::vector &v1, const std::vector &v2) { + auto cmp_func = [](const std::vector &v1, const std::vector &v2) { return v1.size() > v2.size(); // sort by vector size }; - std::stable_sort(groups.begin(), groups.end(), compare_func); // using stable sort for ordered index + std::stable_sort(groups.begin(), groups.end(), cmp_func); // using stable sort for ordered index return groups; } diff --git a/src/klotski_core/group/group.h b/src/klotski_core/group/group.h index 6a886a9..645b1b9 100644 --- a/src/klotski_core/group/group.h +++ b/src/klotski_core/group/group.h @@ -39,8 +39,13 @@ public: static block_num_t block_num(const CommonCode &common_code) noexcept; }; -inline bool operator==(const TypeId &t1, const TypeId &t2) { return t1.unwrap() == t2.unwrap(); } -inline bool operator!=(const TypeId &t1, const TypeId &t2) { return t1.unwrap() != t2.unwrap(); } +inline bool operator==(const TypeId &t1, const TypeId &t2) { + return t1.unwrap() == t2.unwrap(); +} + +inline bool operator!=(const TypeId &t1, const TypeId &t2) { + return t1.unwrap() != t2.unwrap(); +} inline bool operator==(const TypeId::block_num_t &b1, const TypeId::block_num_t &b2) { return (b1.n_1x1 == b2.n_1x1) && (b1.n_1x2 == b2.n_1x2) && (b1.n_2x1 == b2.n_2x1); @@ -79,6 +84,7 @@ class Group { public: /// ----------------------------------- group seeds ----------------------------------- + /// Get the minimum CommonCode of the specified group. static CommonCode group_seed(const GroupId &group_id); static CommonCode group_seed(const RawCode &raw_code); static CommonCode group_seed(const CommonCode &common_code); @@ -99,7 +105,7 @@ public: static std::vector> build_groups(const TypeId &type_id); /// Calculate the specified group using type_id and group_id. - static std::vector build_group(const GroupId &group_id); + static std::vector build_group(const GroupId &group_id); /// ----------------------------------- group info ------------------------------------ @@ -109,10 +115,8 @@ public: uint32_t group_index; }; - /// Get group info according to RawCode. + /// Get group info according to specified case. static group_info_t group_info(const RawCode &raw_code); - - /// Get group info according to CommonCode. static group_info_t group_info(const CommonCode &common_code); /// Get the CommonCode according to the group info. diff --git a/src/klotski_core/group/seeds.cc b/src/klotski_core/group/seeds.cc index a26fb26..edb2830 100644 --- a/src/klotski_core/group/seeds.cc +++ b/src/klotski_core/group/seeds.cc @@ -1,3 +1,4 @@ +#include #include "group.h" #include "type_id.h" #include "group_seeds.h" @@ -6,40 +7,25 @@ namespace klotski { +CommonCode Group::group_seed(const CommonCode &common_code) { + return group_seed(common_code.to_raw_code()); +} +CommonCode Group::group_seed(const RawCode &raw_code) { + auto cases = group_cases(raw_code); + std::vector group(cases.begin(), cases.end()); + return *std::min_element(group.begin(), group.end()); +} CommonCode Group::group_seed(const GroupId &group_id) { - - // TODO: check value - - auto type_id = group_id.type_id(); - - auto offset = TYPE_ID_OFFSET[type_id]; - - std::cout << "size: " << TYPE_ID_GROUP_NUM[type_id] << std::endl; - - auto k = GROUP_SEEDS_INDEX[offset + group_id.unwrap()]; - - std::cout << "tmp index: " << k << std::endl; - - auto r = k + offset; - - std::cout << "real index: " << r << std::endl; - - auto seed = CommonCode(GROUP_SEEDS[r]); - - std::cout << "seed: " << seed << std::endl; - - std::cout << RawCode(seed) << std::endl; - - return seed; + auto offset = TYPE_ID_OFFSET[group_id.type_id()]; // type id offset + auto index = offset + GROUP_SEEDS_INDEX[offset + group_id.unwrap()]; + return CommonCode::unsafe_create(GROUP_SEEDS[index]); } std::vector Group::group_seeds(const TypeId &type_id) { - auto offset = GROUP_SEEDS + TYPE_ID_OFFSET[type_id.unwrap()]; // group id offset + auto offset = GROUP_SEEDS + TYPE_ID_OFFSET[type_id.unwrap()]; // type id offset return {offset, offset + TYPE_ID_GROUP_NUM[type_id.unwrap()]}; } - - } // namespace klotski