Browse Source

perf: group module

master
Dnomd343 1 year ago
parent
commit
bf56576eb0
  1. 18
      src/klotski_core/group/build_cases.cc
  2. 36
      src/klotski_core/group/group.h
  3. 9
      src/klotski_core/group/group_info.cc
  4. 5
      src/klotski_core/group/seeds.cc

18
src/klotski_core/group/build_cases.cc

@ -14,7 +14,7 @@ using Common::range_reverse;
/// --------------------------------------- Group Type ----------------------------------------
std::vector<CommonCode> GroupType::cases() const noexcept {
CommonCodes GroupType::cases() const noexcept {
std::vector<uint32_t> ranges; // basic ranges of type_id
ranges.reserve(TYPE_ID_SIZE[type_id_]); // over-allocation
@ -48,9 +48,9 @@ std::vector<CommonCode> GroupType::cases() const noexcept {
return all_cases;
}
std::vector<std::vector<CommonCode>> GroupType::groups() const noexcept {
std::vector<CommonCodes> GroupType::groups() const noexcept {
auto all_cases = GroupType::cases();
std::vector<std::vector<CommonCode>> groups;
std::vector<CommonCodes> 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
@ -60,18 +60,18 @@ std::vector<std::vector<CommonCode>> GroupType::groups() const noexcept {
}
absl::btree_set<CommonCode> cases(all_cases.begin(), all_cases.end());
for (auto &&tmp : *groups.begin()) {
for (auto &&tmp : groups.front()) {
cases.erase(tmp); // remove elements from first group
}
while (!cases.empty()) {
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)) {
for (auto &&tmp : groups.back()) {
cases.erase(tmp); // remove selected cases
}
}
auto cmp_func = [](const std::vector<CommonCode> &v1, const std::vector<CommonCode> &v2) {
auto cmp_func = [](const CommonCodes &v1, const CommonCodes &v2) {
return v1.size() > v2.size(); // sort by vector size
};
std::stable_sort(groups.begin(), groups.end(), cmp_func); // using stable sort for ordered index
@ -114,15 +114,15 @@ uint32_t Group::size(const RawCode &raw_code) noexcept {
/// --------------------------------------- Group Cases ---------------------------------------
std::vector<RawCode> Group::cases() const noexcept {
RawCodes Group::cases() const noexcept {
return cases(seed());
}
std::vector<RawCode> Group::cases(const CommonCode &common_code) noexcept {
RawCodes Group::cases(const CommonCode &common_code) noexcept {
return cases(common_code.to_raw_code());
}
std::vector<RawCode> Group::cases(const RawCode &raw_code) noexcept {
RawCodes Group::cases(const RawCode &raw_code) noexcept {
std::queue<uint64_t> cache({raw_code.unwrap()});
absl::flat_hash_map<uint64_t, uint64_t> cases; // <code, mask>
cases.reserve(GroupType::max_size(raw_code));

36
src/klotski_core/group/group.h

@ -113,7 +113,7 @@ public:
std::vector<CommonCode> cases() const noexcept;
/// Calculate all groups of the current type_id.
std::vector<std::vector<CommonCode>> groups() const noexcept;
std::vector<CommonCodes> groups() const noexcept;
};
/// ------------------------------------------ Group ------------------------------------------
@ -145,9 +145,9 @@ public:
static CommonCode seed(const CommonCode &common_code) noexcept;
/// Calculate the current group.
std::vector<RawCode> cases() const noexcept;
static std::vector<RawCode> cases(const RawCode &raw_code) noexcept;
static std::vector<RawCode> cases(const CommonCode &common_code) noexcept;
RawCodes cases() const noexcept;
static RawCodes cases(const RawCode &raw_code) noexcept;
static RawCodes cases(const CommonCode &common_code) noexcept;
};
/// --------------------------------------- Group Case ----------------------------------------
@ -177,22 +177,34 @@ public:
inline bool operator==(const GroupType &t1, const GroupType &t2) {
return t1.unwrap() == t2.unwrap();
}
inline bool operator!=(const GroupType &t1, const GroupType &t2) {
return !(t1 == t2);
}
inline bool operator==(const Group &g1, const Group &g2) {
return g1.type_id() == g2.type_id() && g1.unwrap() == g2.unwrap();
return g1.type_id() == g2.type_id()
&& g1.unwrap() == g2.unwrap();
}
inline bool operator!=(const Group &g1, const Group &g2) {
return !(g1 == g2);
}
inline bool operator==(const GroupType::block_num_t &b1, const GroupType::block_num_t &b2) {
return (b1.n_1x1 == b2.n_1x1) && (b1.n_1x2 == b2.n_1x2) && (b1.n_2x1 == b2.n_2x1);
return (b1.n_1x1 == b2.n_1x1)
&& (b1.n_1x2 == b2.n_1x2)
&& (b1.n_2x1 == b2.n_2x1);
}
inline bool operator!=(const GroupType::block_num_t &b1, const GroupType::block_num_t &b2) {
return !(b1 == b2);
}
inline bool operator==(const GroupCase::info_t &i1, const GroupCase::info_t &i2) {
return (i1.type_id == i2.type_id) && (i1.group_id == i2.group_id) && (i1.group_index == i2.group_index);
return (i1.type_id == i2.type_id)
&& (i1.group_id == i2.group_id)
&& (i1.group_index == i2.group_index);
}
inline bool operator!=(const GroupCase::info_t &i1, const GroupCase::info_t &i2) {
return !(i1 == i2);
}
inline bool operator!=(const Group &g1, const Group &g2) { return !(g1 == g2); }
inline bool operator!=(const GroupType &t1, const GroupType &t2) { return !(t1 == t2); }
inline bool operator!=(const GroupCase::info_t &i1, const GroupCase::info_t &i2) { return !(i1 == i2); }
inline bool operator!=(const GroupType::block_num_t &b1, const GroupType::block_num_t &b2) { return !(b1 == b2); }
} // namespace klotski

9
src/klotski_core/group/group_info.cc

@ -44,17 +44,16 @@ CommonCode GroupCase::parse(const info_t &info) {
throw std::invalid_argument("group index overflow"); // check group index
}
std::vector<CommonCode> group(cases.begin(), cases.end());
auto group = CommonCode::convert(cases);
std::nth_element(group.begin(), group.begin() + info.group_index, group.end());
return group[info.group_index]; // located nth as target
}
GroupCase::info_t GroupCase::encode(const CommonCode &common_code) noexcept {
uint32_t group_index = 0;
auto cases = Group::cases(common_code);
std::vector<CommonCode> group(cases.begin(), cases.end());
for (auto &&code: group) {
if (code < common_code) {
auto group = CommonCode::convert(Group::cases(common_code));
for (auto &&tmp: group) {
if (tmp < common_code) {
++group_index; // locate group index
}
}

5
src/klotski_core/group/seeds.cc

@ -3,8 +3,6 @@
#include "type_id.h"
#include "group_seeds.h"
#include <iostream>
namespace klotski {
std::vector<CommonCode> GroupType::seeds() const noexcept {
@ -19,8 +17,7 @@ CommonCode Group::seed() const noexcept { // group_id -> seed
}
CommonCode Group::seed(const RawCode &raw_code) noexcept {
auto cases = Group::cases(raw_code);
std::vector<CommonCode> group(cases.begin(), cases.end());
auto group = CommonCode::convert(Group::cases(raw_code));
return *std::min_element(group.begin(), group.end());
}

Loading…
Cancel
Save