#include "group/group.h" // #include // #include // #include // #include #include #include #include "constant/group_union.h" static KLSK_INLINE uint32_t type_id(const int n, const int n_2x1, const int n_1x1) { constexpr int offset[8] = {0, 15, 41, 74, 110, 145, 175, 196}; return offset[n] + (15 - n * 2) * n_2x1 + n_1x1; } static uint32_t common_code_to_type_id(const uint64_t common_code) { const auto range = static_cast(common_code); const auto n_1x1 = std::popcount((range >> 1) & range & 0x55555555); const auto n_2x1 = std::popcount((range >> 1) & ~range & 0x55555555); return type_id(std::popcount(range) - n_1x1 * 2, n_2x1, n_1x1); } static uint32_t raw_code_to_type_id(const uint64_t raw_code) { const auto n = std::popcount(((raw_code >> 1) ^ raw_code) & 0x0249249249249249); const auto n_2x1 = std::popcount((raw_code >> 1) & ~raw_code & 0x0249249249249249); const auto n_1x1 = std::popcount((raw_code >> 1) & raw_code & 0x0249249249249249) - n - 3; return type_id(n, n_2x1, n_1x1); } uint32_t klotski::cases::GroupUnion::type_id(codec::CommonCode common_code) { return common_code_to_type_id(common_code.unwrap()); } uint32_t klotski::cases::GroupUnion::type_id(codec::RawCode raw_code) { return raw_code_to_type_id(raw_code.unwrap()); } klotski::cases::RangesUnion klotski::cases::GroupUnion::cases() const { Ranges ranges {}; auto [n, n_2x1, n_1x1] = BLOCK_NUM[type_id_]; // int n = TYPE_ID_N_NUM[type_id_]; // int n_2x1 = TYPE_ID_N_2x1_NUM[type_id_]; // int n_1x1 = TYPE_ID_N_1x1_NUM[type_id_]; // TODO: cal from type_id ranges.spawn(n, n_2x1, n_1x1); // for (int i = 0; i < TYPE_ID_LIMIT; ++i) { // ranges.spawn(TYPE_ID_N_NUM[i], TYPE_ID_N_2x1_NUM[i], TYPE_ID_N_1x1_NUM[i]); // } // std::stable_sort(ranges.begin(), ranges.end()); // for (auto &x : ranges) { // x = klotski::range_reverse(x); // } ranges.reverse(); // auto do_assert = [](uint32_t lhs, uint32_t rhs) { // if (lhs != rhs) { // std::cout << "error" << std::endl; // } // }; RangesUnion cases; // cases[0x0].reserve(7815); // cases[0x1].reserve(6795); // cases[0x2].reserve(7815); // // cases[0x4].reserve(3525); // cases[0x5].reserve(3465); // cases[0x6].reserve(3525); // // cases[0x8].reserve(3525); // cases[0x9].reserve(3465); // cases[0xA].reserve(3525); // // cases[0xC].reserve(7815); // cases[0xD].reserve(6795); // cases[0xE].reserve(7815); auto [A, B, C, D] = GROUP_UNION_CASES_NUM[type_id_]; cases[0x0].reserve(A); cases[0x1].reserve(B); cases[0x2].reserve(A); cases[0x4].reserve(C); cases[0x5].reserve(D); cases[0x6].reserve(C); cases[0x8].reserve(C); cases[0x9].reserve(D); cases[0xA].reserve(C); cases[0xC].reserve(A); cases[0xD].reserve(B); cases[0xE].reserve(A); ranges.derive(0x0, cases[0x0]); ranges.derive(0x1, cases[0x1]); ranges.derive(0x2, cases[0x2]); ranges.derive(0x4, cases[0x4]); ranges.derive(0x5, cases[0x5]); ranges.derive(0x6, cases[0x6]); ranges.derive(0x8, cases[0x8]); ranges.derive(0x9, cases[0x9]); ranges.derive(0xA, cases[0xA]); ranges.derive(0xC, cases[0xC]); ranges.derive(0xD, cases[0xD]); ranges.derive(0xE, cases[0xE]); // uint32_t A = cases[0x0].size(); // uint32_t B = cases[0x1].size(); // uint32_t C = cases[0x4].size(); // uint32_t D = cases[0x5].size(); // // do_assert(cases[0x2].size(), A); // do_assert(cases[0x6].size(), C); // do_assert(cases[0x8].size(), C); // do_assert(cases[0x9].size(), D); // do_assert(cases[0xA].size(), C); // do_assert(cases[0xC].size(), A); // do_assert(cases[0xD].size(), B); // do_assert(cases[0xE].size(), A); // // std::cout << A << ", " << B << ", " << C << ", " << D << std::endl; // auto [A, B, C, D] = kk[type_id_]; // do_assert(cases[0x0].size(), A); // do_assert(cases[0x1].size(), B); // do_assert(cases[0x2].size(), A); // // do_assert(cases[0x4].size(), C); // do_assert(cases[0x5].size(), D); // do_assert(cases[0x6].size(), C); // // do_assert(cases[0x8].size(), C); // do_assert(cases[0x9].size(), D); // do_assert(cases[0xA].size(), C); // // do_assert(cases[0xC].size(), A); // do_assert(cases[0xD].size(), B); // do_assert(cases[0xE].size(), A); return cases; }