From 85bad70c6379c25e6f389053ab478285fd8489ba Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sun, 22 Sep 2024 10:53:13 +0800 Subject: [PATCH] feat: support group cases fast convert --- src/core/group/group.h | 44 ++++++++++---- src/core/group/internal/group_cases.cc | 79 ++++++++++++++++--------- src/core/group/internal/group_cases.inl | 29 +++++++++ src/core/main.cc | 11 ++-- 4 files changed, 121 insertions(+), 42 deletions(-) create mode 100644 src/core/group/internal/group_cases.inl diff --git a/src/core/group/group.h b/src/core/group/group.h index a5e9ced..84e2c75 100644 --- a/src/core/group/group.h +++ b/src/core/group/group.h @@ -200,42 +200,64 @@ public: class GroupCases { public: + // TODO: rename as Info and changed as class struct info_t { uint16_t type_id; uint16_t group_id; uint32_t case_id; - // TODO: should we keep it valid? (convert without check) +#ifndef KLSK_NDEBUG + friend std::ostream& operator<<(std::ostream &out, info_t self) { + out << std::format("{}-{}-{}", self.type_id, self.group_id, self.case_id); + return out; + } +#endif + + // TODO: keep info_t valid (convert without check) }; + // ------------------------------------------------------------------------------------- // + /// Execute the build process. void build(); /// Execute the build process without blocking. void build_async(Executor &&executor, Notifier &&callback); - static info_t to_info_t(codec::ShortCode short_code); + // ------------------------------------------------------------------------------------- // - static codec::CommonCode from_info_t(info_t info); + /// Parse CommonCode from group info. + codec::CommonCode parse(info_t info); + + /// Get group info from RawCode. + info_t group_info(codec::RawCode raw_code); + + /// Get group info from short code. + info_t group_info(codec::ShortCode short_code); - /// Get the CommonCode using the group info. - // static codec::CommonCode parse(const info_t &info); + /// Get group info from common code. + info_t group_info(codec::CommonCode common_code); - /// Get group info according to specified case. - // static info_t encode(const codec::RawCode &raw_code); - // static info_t encode(const codec::CommonCode &common_code); + // ------------------------------------------------------------------------------------- // private: bool available_ = false; std::mutex building_ {}; - // static codec::CommonCode fast_decode(const info_t &info); - // static info_t fast_encode(const codec::CommonCode &common_code); - KLSK_INSTANCE(GroupCases) + +public: + // fast api + static info_t to_info_t(codec::ShortCode short_code); + static codec::CommonCode from_info_t(info_t info); + + // TODO: add to_info_t(CommonCode) interface + + // TODO: tiny api }; } // namespace klotski::cases #include "internal/group_union.inl" +#include "internal/group_cases.inl" #include "internal/group.inl" diff --git a/src/core/group/internal/group_cases.cc b/src/core/group/internal/group_cases.cc index 6646f4b..76f7403 100644 --- a/src/core/group/internal/group_cases.cc +++ b/src/core/group/internal/group_cases.cc @@ -5,10 +5,20 @@ using klotski::cases::GroupCases; +using klotski::codec::ShortCode; + using klotski::codec::CommonCode; using klotski::cases::RangesUnion; +using klotski::cases::GroupUnion; + +using klotski::cases::ALL_GROUP_NUM; + +using klotski::cases::TYPE_ID_LIMIT; + +using klotski::cases::ALL_CASES_NUM_; + struct tmp_t { uint32_t group_id : 12; uint32_t case_id : 20; @@ -21,38 +31,26 @@ static_assert(sizeof(tmp_t) == 4); std::vector build_ranges_unions() { std::vector unions; - unions.reserve(25422); - - // auto group_union = klotski::cases::GroupUnion::unsafe_create(169); + unions.reserve(ALL_GROUP_NUM); // TODO: add white list for single-group unions - for (uint32_t type_id = 0; type_id < klotski::cases::TYPE_ID_LIMIT; ++type_id) { - auto group_union = klotski::cases::GroupUnion::unsafe_create(type_id); + 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()) { unions.emplace_back(group.cases()); } } - std::cout << unions.size() << std::endl; - return unions; } CommonCode GroupCases::from_info_t(info_t info) { - std::vector data = build_ranges_unions(); - - // TODO: build as static data - - // TODO: loop [0, 25422) -> get RangesUnion of all flat_ids + // TODO: build as static class member (ptr) + static std::vector data = build_ranges_unions(); auto flat_id = GROUP_OFFSET[info.type_id] + info.group_id; - std::cout << "flat_id = " << flat_id << std::endl; - - // auto codes = data[flat_id].codes(); - // std::stable_sort(codes.begin(), codes.end()); - // std::cout << codes[info.case_id] << std::endl; auto &cases = data[flat_id]; // TODO: make offset table for perf @@ -68,23 +66,50 @@ CommonCode GroupCases::from_info_t(info_t info) { } } - std::cout << "head = " << head << std::endl; - std::cout << info.case_id << std::endl; + auto range = cases[head][info.case_id]; + return CommonCode::unsafe_create(head << 32 | range); +} - // TODO: need sort in `Group::cases` - std::stable_sort(cases[head].begin(), cases[head].end()); +static std::vector build_tmp_data() { - std::cout << CommonCode::unsafe_create(head << 32 | cases[1][1909]) << std::endl; + std::vector 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()) { + uint32_t group_id = group.group_id(); + + 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()] = tmp_t { + .group_id = group_id, + .case_id = case_id, + }; + + } + } + } + + return data; - return CommonCode::unsafe_create(0); } GroupCases::info_t GroupCases::to_info_t(codec::ShortCode short_code) { - std::vector data; - // TODO: build as static data + // TODO: build as static class member (ptr) + static auto data = build_tmp_data(); - // TODO: loop from `std::vector` + uint16_t type_id = GroupUnion::from_short_code(short_code).unwrap(); // NOTE: need to convert as CommonCode + uint16_t group_id = data[short_code.unwrap()].group_id; + auto case_id = data[short_code.unwrap()].case_id; - return {}; + return info_t { + .type_id = type_id, + .group_id = group_id, + .case_id = case_id, + }; } diff --git a/src/core/group/internal/group_cases.inl b/src/core/group/internal/group_cases.inl new file mode 100644 index 0000000..d803a56 --- /dev/null +++ b/src/core/group/internal/group_cases.inl @@ -0,0 +1,29 @@ +#pragma once + +namespace klotski::cases { + +inline void GroupCases::build() { + +} + +inline void GroupCases::build_async(Executor &&executor, Notifier &&callback) { + +} + +inline codec::CommonCode GroupCases::parse(GroupCases::info_t info) { + return codec::CommonCode::unsafe_create(0); +} + +inline GroupCases::info_t GroupCases::group_info(codec::RawCode raw_code) { + return info_t {}; +} + +inline GroupCases::info_t GroupCases::group_info(codec::ShortCode short_code) { + return info_t {}; +} + +inline GroupCases::info_t GroupCases::group_info(codec::CommonCode common_code) { + return info_t {}; +} + +} // namespace klotski::cases diff --git a/src/core/main.cc b/src/core/main.cc index e55c65f..0e64083 100644 --- a/src/core/main.cc +++ b/src/core/main.cc @@ -40,11 +40,14 @@ int main() { const auto start = std::chrono::system_clock::now(); - const auto common_code = CommonCode::unsafe_create(0x1A9BF0C00); - const auto group = Group::from_common_code(common_code); +// const auto common_code = CommonCode::unsafe_create(0x1A9BF0C00); +// const auto group = Group::from_common_code(common_code); - // GroupCases::from_info_t({169, 1, 7472}); - // GroupCases::to_info_t(CommonCode::unsafe_create(0x1A9BF0C00).to_short_code()); + std::cout << GroupCases::from_info_t({169, 1, 7472}) << std::endl; + std::cout << GroupCases::from_info_t({164, 0, 30833}) << std::endl; + + std::cout << GroupCases::to_info_t(CommonCode::unsafe_create(0x1A9BF0C00).to_short_code()) << std::endl; + std::cout << GroupCases::to_info_t(CommonCode::unsafe_create(0x4FEA13400).to_short_code()) << std::endl; std::cerr << std::chrono::system_clock::now() - start << std::endl;