华容道高性能计算引擎
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

88 lines
2.7 KiB

#include <absl/container/flat_hash_map.h>
#include "mover/mover.h"
#include "group/group.h"
//using klotski::cases::Group;
using klotski::codec::RawCode;
using klotski::codec::CommonCode;
using klotski::cases::RangesUnion;
using klotski::mover::MaskMover;
using klotski::cases::GroupUnion;
std::vector<RawCode> klotski::cases::Group_extend(RawCode raw_code, uint32_t reserve) {
std::vector<RawCode> codes;
absl::flat_hash_map<uint64_t, uint64_t> cases; // <code, mask>
reserve = reserve ? reserve : GroupUnion::from_raw_code(raw_code).max_group_size();
codes.reserve(reserve);
cases.reserve(reserve);
auto core = MaskMover([&codes, &cases](uint64_t code, uint64_t mask) {
if (const auto match = cases.find(code); match != cases.end()) {
match->second |= mask; // update mask
return;
}
cases.emplace(code, mask);
codes.emplace_back(RawCode::unsafe_create(code)); // new case
});
uint64_t offset = 0;
codes.emplace_back(raw_code);
cases.emplace(raw_code, 0); // without mask
while (offset != codes.size()) {
auto curr = codes[offset++].unwrap();
core.next_cases(curr, cases.find(curr)->second);
}
return codes;
}
//RangesUnion Group::cases() const {
//
// // TODO: add white list for single-group unions
// // return GroupUnion::cases directly
//
// auto seed = CommonCode::unsafe_create(GROUP_SEED[flat_id()]);
//
// // std::cout << seed << std::endl;
//
// auto codes = Group_extend(seed.to_raw_code(), size());
//
// // std::cout << codes.size() << std::endl;
//
// // TODO: how to reserve
//
// RangesUnion data;
//
// for (auto raw_code : codes) {
// auto common_code = raw_code.to_common_code().unwrap();
// data[common_code >> 32].emplace_back(static_cast<uint32_t>(common_code));
// }
//
// // TODO: do sort process
//
// for (int head = 0; head < 16; ++head) {
// std::stable_sort(data[head].begin(), data[head].end());
// }
//
// return data;
//}
//Group Group::from_raw_code(codec::RawCode raw_code) {
//
// auto raw_codes = Group_extend(raw_code);
//
// auto common_codes = raw_codes | std::views::transform([](const RawCode r) {
// return r.to_common_code();
// }) | std::ranges::to<std::vector>(); // TODO: search min_element directly
//
// auto seed = std::min_element(common_codes.begin(), common_codes.end());
//
// std::cout << *seed << std::endl;
//
// // TODO: search type_id / group_id from map
// auto flat_id = std::find(GROUP_SEED.begin(), GROUP_SEED.end(), *seed) - GROUP_SEED.begin();
// std::cout << flat_id << std::endl;
//
// return Group::unsafe_create(0, 0); // TODO: only for compile
//}