mirror of https://github.com/dnomd343/klotski.git
Dnomd343
3 months ago
3 changed files with 66 additions and 128 deletions
@ -1,99 +1,81 @@ |
|||||
#include <iostream> |
|
||||
|
|
||||
#include "cases.h" |
#include "cases.h" |
||||
|
|
||||
/// Filter cases with different type_id from AllCases.
|
// TODO: multi-threads builder
|
||||
static std::vector<std::vector<CommonCode>> build_all_cases() { |
|
||||
std::vector<std::vector<CommonCode>> codes; |
|
||||
for (auto code : AllCases::instance().fetch().codes()) { |
|
||||
const auto type_id = to_type_id(cal_block_num(code.unwrap())); |
|
||||
if (type_id >= codes.size()) { |
|
||||
codes.resize(type_id + 1); |
|
||||
} |
|
||||
codes[type_id].emplace_back(code); |
|
||||
} |
|
||||
return codes; |
|
||||
} |
|
||||
|
|
||||
std::vector<CommonCode> extend_cases(CommonCode seed) { |
/// Extend ordered Group from the specified CommonCode seed.
|
||||
auto raw_codes = klotski::cases::Group::extend(seed.to_raw_code()); // TODO: using inner build process
|
static std::vector<CommonCode> extend_cases(CommonCode seed) { |
||||
|
// TODO: using inner build process
|
||||
|
auto raw_codes = klotski::cases::Group::extend(seed.to_raw_code()); |
||||
std::vector<CommonCode> common_codes {raw_codes.begin(), raw_codes.end()}; |
std::vector<CommonCode> common_codes {raw_codes.begin(), raw_codes.end()}; |
||||
std::ranges::sort(common_codes.begin(), common_codes.end()); |
std::ranges::sort(common_codes.begin(), common_codes.end()); |
||||
return common_codes; |
return common_codes; |
||||
} |
} |
||||
|
|
||||
std::vector<CommonCode> remove_sub(const std::vector<CommonCode> &all, const std::vector<CommonCode> &sub) { |
/// Split Groups from the specified ordered list of CommonCodes.
|
||||
std::vector<CommonCode> tmp; |
|
||||
tmp.reserve(all.size() - sub.size()); |
|
||||
std::ranges::set_difference(all.begin(), all.end(), sub.begin(), sub.end(), std::back_inserter(tmp)); |
|
||||
return tmp; |
|
||||
} |
|
||||
|
|
||||
static std::vector<std::vector<CommonCode>> split_groups(std::vector<CommonCode> codes) { |
static std::vector<std::vector<CommonCode>> split_groups(std::vector<CommonCode> codes) { |
||||
|
|
||||
std::vector<std::vector<CommonCode>> groups; |
std::vector<std::vector<CommonCode>> groups; |
||||
|
|
||||
while (!codes.empty()) { |
while (!codes.empty()) { |
||||
auto sub = extend_cases(codes[0]); |
auto group = extend_cases(codes[0]); // sorted array
|
||||
|
groups.emplace_back(group); |
||||
|
|
||||
groups.emplace_back(sub); |
std::vector<CommonCode> remain; |
||||
codes = remove_sub(codes, sub); |
remain.reserve(codes.size() - group.size()); |
||||
|
std::ranges::set_difference(codes.begin(), codes.end(), group.begin(), group.end(), std::back_inserter(remain)); |
||||
|
codes = remain; // for next loop
|
||||
} |
} |
||||
|
std::ranges::stable_sort(groups.begin(), groups.end(), [](const auto &lhs, const auto &rhs) { |
||||
std::ranges::stable_sort(groups.begin(), groups.end(), [](const std::vector<CommonCode> &g1, const std::vector<CommonCode> &g2) { |
return lhs.size() > rhs.size(); // sort with group size
|
||||
return g1.size() > g2.size(); |
|
||||
}); |
}); |
||||
|
|
||||
return groups; |
return groups; |
||||
|
|
||||
} |
} |
||||
|
|
||||
// TODO: static data of `build_all_cases`
|
/// Filter cases with different type_id from AllCases.
|
||||
|
static const std::vector<std::vector<CommonCode>>& group_union_data() { |
||||
uint32_t group_union_num() { |
static auto data = [] { |
||||
static auto data = build_all_cases(); |
std::vector<std::vector<CommonCode>> codes; |
||||
return data.size(); |
codes.resize(block_nums().size()); |
||||
} |
for (auto code: AllCases::instance().fetch().codes()) { |
||||
|
codes[to_type_id(cal_block_num(code.unwrap()))].emplace_back(code); |
||||
const std::vector<CommonCode>& group_union_cases(const uint32_t type_id) { |
|
||||
static auto data = build_all_cases(); |
|
||||
if (type_id < data.size()) { |
|
||||
return data[type_id]; |
|
||||
} |
} |
||||
std::abort(); |
return codes; |
||||
|
}(); |
||||
|
return data; |
||||
} |
} |
||||
|
|
||||
// TODO: multi-threads builder
|
/// Construct all valid klotski Groups in different GroupUnion.
|
||||
|
static const std::vector<std::vector<std::vector<CommonCode>>>& group_data() { |
||||
static std::vector<std::vector<std::vector<CommonCode>>> all_groups_builder() { |
static auto data = [] { |
||||
|
std::vector<std::vector<std::vector<CommonCode>>> groups; |
||||
std::vector<std::vector<std::vector<CommonCode>>> data; |
groups.reserve(group_union_num()); |
||||
|
|
||||
for (uint32_t type_id = 0; type_id < group_union_num(); ++type_id) { |
for (uint32_t type_id = 0; type_id < group_union_num(); ++type_id) { |
||||
|
groups.emplace_back(split_groups(group_union_cases(type_id))); |
||||
data.emplace_back(split_groups(group_union_cases(type_id))); |
|
||||
|
|
||||
} |
} |
||||
|
return groups; |
||||
|
}(); |
||||
return data; |
return data; |
||||
|
} |
||||
|
|
||||
|
uint32_t group_union_num() { |
||||
|
return group_union_data().size(); |
||||
} |
} |
||||
|
|
||||
uint32_t group_num(uint32_t type_id) { |
uint32_t group_num(uint32_t type_id) { |
||||
static auto data = all_groups_builder(); |
if (type_id < group_data().size()) { |
||||
if (type_id < data.size()) { |
return group_data()[type_id].size(); |
||||
return data[type_id].size(); |
|
||||
} |
} |
||||
std::abort(); |
std::abort(); |
||||
} |
} |
||||
|
|
||||
const std::vector<CommonCode>& group_cases(uint32_t type_id, uint32_t group_id) { |
const std::vector<CommonCode>& group_union_cases(const uint32_t type_id) { |
||||
|
if (type_id < group_union_data().size()) { |
||||
static auto data = all_groups_builder(); |
return group_union_data()[type_id]; |
||||
|
|
||||
if (type_id < data.size() && group_id < data[type_id].size()) { |
|
||||
return data[type_id][group_id]; |
|
||||
} |
} |
||||
|
std::abort(); |
||||
|
} |
||||
|
|
||||
|
const std::vector<CommonCode>& group_cases(uint32_t type_id, uint32_t group_id) { |
||||
|
if (type_id < group_data().size() && group_id < group_data()[type_id].size()) { |
||||
|
return group_data()[type_id][group_id]; |
||||
|
} |
||||
std::abort(); |
std::abort(); |
||||
} |
} |
||||
|
Loading…
Reference in new issue