华容道高性能计算引擎
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.
 
 
 
 
 

66 lines
2.1 KiB

#include <algorithm>
#include "group/group.h"
using klotski::codec::RawCode;
using klotski::codec::CommonCode;
using klotski::cases::GroupPro;
using klotski::cases::RangesUnion;
using klotski::cases::GROUP_DATA;
using klotski::cases::PATTERN_DATA;
RangesUnion GroupPro::cases() const {
auto seed = CommonCode::unsafe_create(PATTERN_DATA[flat_id()] >> 23);
// NOTE: convert as RawCode directly
if (toward_ == Toward::B) {
seed = seed.to_horizontal_mirror();
} else if (toward_ == Toward::C) {
seed = seed.to_vertical_mirror();
} else if (toward_ == Toward::D) {
// NOTE: avoid multi convert
seed = seed.to_vertical_mirror().to_horizontal_mirror();
}
auto codes = Group::extend(seed.to_raw_code(), size());
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));
}
for (int head = 0; head < 16; ++head) {
std::stable_sort(data[head].begin(), data[head].end());
}
return data;
}
static std::unordered_map<uint64_t, GroupPro> build_map_data() {
// NOTE: using CommonCode as map key
std::unordered_map<uint64_t, GroupPro> data;
data.reserve(GROUP_DATA.size());
for (auto raw : GROUP_DATA) {
uint32_t type_id = (raw >> 12) & 0b11111111;
uint32_t pattern_id = (raw >> 2) & 0b1111111111;
uint32_t toward = raw & 0b11;
auto seed = CommonCode::unsafe_create(raw >> 20).unwrap();
auto group = GroupPro::unsafe_create(type_id, pattern_id, (GroupPro::Toward)toward);
data.emplace(seed, group);
}
return data;
}
GroupPro GroupPro::from_raw_code(codec::RawCode raw_code) {
static auto map_data = build_map_data();
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());
return map_data.at(seed->unwrap());
}