Browse Source

feat: parse and obtain case info

master
Dnomd343 4 weeks ago
parent
commit
9fd51d99d0
  1. 1
      src/core/CMakeLists.txt
  2. 17
      src/core/group/group.h
  3. 121
      src/core/group/internal/group_cases_pro.cc
  4. 41
      src/core/main.cc

1
src/core/CMakeLists.txt

@ -27,6 +27,7 @@ set(KLOTSKI_CORE_SRC
group/internal/group.cc
group/internal/group_pro.cc
group/internal/group_cases.cc
group/internal/group_cases_pro.cc
ranges/internal/spawn.cc
ranges/internal/ranges.cc

17
src/core/group/group.h

@ -272,6 +272,23 @@ public:
static std::vector<codec::RawCode> extend(codec::RawCode raw_code, uint32_t reserve = 0);
};
class GroupCasesPro {
public:
struct CaseInfo {
GroupPro group;
uint32_t case_id;
};
// TODO: allow cal Group directly
static void build();
static codec::CommonCode fast_parse(CaseInfo info);
static CaseInfo fast_obtain(codec::ShortCode short_code);
};
class GroupCases {
public:
// TODO: rename as Info and changed as class

121
src/core/group/internal/group_cases_pro.cc

@ -0,0 +1,121 @@
#include <iostream>
#include "group/group.h"
using klotski::codec::ShortCode;
using klotski::codec::CommonCode;
using klotski::cases::GroupPro;
using klotski::cases::GroupUnion;
using klotski::cases::RangesUnion;
using klotski::cases::GroupCasesPro;
using klotski::cases::ALL_GROUP_NUM;
using klotski::cases::TYPE_ID_LIMIT;
using klotski::cases::ALL_CASES_NUM_;
struct case_info_t {
uint32_t pattern_id : 10;
uint32_t toward_id : 2;
uint32_t case_id : 20;
};
static_assert(sizeof(case_info_t) == 4);
// TODO: we need multi-thread support (Executor)
static std::vector<std::vector<RangesUnion>> *ru_data = nullptr;
static std::vector<case_info_t> *rev_data = nullptr;
std::vector<std::vector<RangesUnion>> build_ranges_unions() {
std::vector<std::vector<RangesUnion>> unions;
unions.reserve(ALL_GROUP_NUM);
// TODO: add white list for single-group unions
for (uint32_t type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) {
auto group_union = GroupUnion::unsafe_create(type_id);
for (uint32_t pattern_id = 0; pattern_id < group_union.pattern_num(); ++pattern_id) {
std::vector<GroupPro> groups;
for (auto group : group_union.groups_pro()) {
if (group.pattern_id() == pattern_id) {
groups.emplace_back(group);
}
}
std::vector<RangesUnion> tmp {4};
for (auto group : groups) {
tmp[group.mirror_toward()] = group.cases();
}
unions.emplace_back(tmp);
}
}
return unions;
}
static std::vector<case_info_t> build_tmp_data() {
std::vector<case_info_t> data;
data.resize(ALL_CASES_NUM_);
ShortCode::speed_up(true);
for (uint32_t type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) {
auto group_union = GroupUnion::unsafe_create(type_id);
for (auto group : group_union.groups_pro()) {
uint32_t pattern_id = group.pattern_id();
uint32_t toward_id = group.mirror_toward();
// TODO: batch mirror base on pattern
auto codes = group.cases().codes();
for (uint32_t case_id = 0; case_id < codes.size(); ++case_id) {
auto short_code = codes[case_id].to_short_code();
data[short_code.unwrap()] = case_info_t {
.pattern_id = pattern_id,
.toward_id = toward_id,
.case_id = case_id,
};
}
}
}
return data;
}
void GroupCasesPro::build() {
static auto data_1 = build_ranges_unions();
static auto data_2 = build_tmp_data();
ru_data = &data_1;
rev_data = &data_2;
}
CommonCode GroupCasesPro::fast_parse(CaseInfo info) {
auto flat_id = PATTERN_OFFSET[info.group.type_id()] + info.group.pattern_id();
auto &cases = (*ru_data)[flat_id][info.group.mirror_toward()];
// TODO: make offset table for perf
uint64_t head = 0;
for (;;) {
if (info.case_id >= cases[head].size()) {
info.case_id -= cases[head].size();
++head;
} else {
break;
}
}
auto range = cases[head][info.case_id];
return CommonCode::unsafe_create(head << 32 | range);
}
GroupCasesPro::CaseInfo GroupCasesPro::fast_obtain(codec::ShortCode short_code) {
uint16_t type_id = GroupUnion::from_short_code(short_code).unwrap(); // NOTE: need to convert as CommonCode
uint16_t pattern_id = (*rev_data)[short_code.unwrap()].pattern_id;
uint16_t toward_id = (*rev_data)[short_code.unwrap()].toward_id;
auto case_id = (*rev_data)[short_code.unwrap()].case_id;
return CaseInfo {
.group = GroupPro::unsafe_create(type_id, pattern_id, toward_id),
.case_id = case_id,
};
}

41
src/core/main.cc

@ -30,6 +30,7 @@ using klotski::cases::Group;
using klotski::cases::GroupPro;
using klotski::cases::GroupCases;
using klotski::cases::GroupUnion;
using klotski::cases::GroupCasesPro;
using klotski::cases::TYPE_ID_LIMIT;
using klotski::cases::ALL_CASES_NUM_;
@ -43,22 +44,30 @@ int main() {
const auto start = std::chrono::system_clock::now();
ShortCode::speed_up(true);
std::unordered_set<RawCode> data_r;
std::unordered_set<ShortCode> data_s;
std::unordered_set<CommonCode> data_c;
data_r.reserve(ALL_CASES_NUM_);
data_s.reserve(ALL_CASES_NUM_);
data_c.reserve(ALL_CASES_NUM_);
for (auto code : AllCases::instance().fetch().codes()) {
data_c.emplace(code);
data_r.emplace(code.to_raw_code());
data_s.emplace(code.to_short_code());
}
std::cout << data_r.size() << std::endl;
std::cout << data_s.size() << std::endl;
std::cout << data_c.size() << std::endl;
// ShortCode::speed_up(true);
//
// std::unordered_set<RawCode> data_r;
// std::unordered_set<ShortCode> data_s;
// std::unordered_set<CommonCode> data_c;
// data_r.reserve(ALL_CASES_NUM_);
// data_s.reserve(ALL_CASES_NUM_);
// data_c.reserve(ALL_CASES_NUM_);
// for (auto code : AllCases::instance().fetch().codes()) {
// data_c.emplace(code);
// data_r.emplace(code.to_raw_code());
// data_s.emplace(code.to_short_code());
// }
// std::cout << data_r.size() << std::endl;
// std::cout << data_s.size() << std::endl;
// std::cout << data_c.size() << std::endl;
GroupCasesPro::build();
auto kk = GroupCasesPro::fast_obtain(CommonCode::unsafe_create(0x1A9BF0C00).to_short_code());
std::cout << std::format("{}-{}-{}-{}", kk.group.type_id(), kk.group.pattern_id(), kk.group.mirror_toward(), kk.case_id) << std::endl;
auto code = GroupCasesPro::fast_parse(kk);
std::cout << code << std::endl;
// const auto common_code = CommonCode::unsafe_create(0x1A9BF0C00);
// const auto group = Group::from_common_code(common_code);

Loading…
Cancel
Save