mirror of https://github.com/dnomd343/klotski.git
Dnomd343
7 months ago
7 changed files with 130 additions and 192 deletions
@ -0,0 +1,5 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
namespace klotski::cases { |
||||
|
|
||||
|
} // namespace klotski::cases |
@ -1,154 +1,51 @@ |
|||||
|
#include "core/core.h" |
||||
#include "group/group.h" |
#include "group/group.h" |
||||
|
#include "constant/group_union.h" |
||||
|
|
||||
// #include <queue>
|
using klotski::codec::RawCode; |
||||
|
using klotski::codec::CommonCode; |
||||
// #include <absl/container/btree_set.h>
|
using klotski::cases::GroupUnion; |
||||
// #include <absl/container/flat_hash_map.h>
|
|
||||
// #include <absl/container/node_hash_map.h>
|
|
||||
|
|
||||
#include <iostream> |
|
||||
#include <core/core.h> |
|
||||
|
|
||||
#include "constant/group_union.h" |
#define RANGE_DERIVE(HEAD) ranges.derive(HEAD, cases[HEAD]) |
||||
|
|
||||
static KLSK_INLINE uint32_t type_id(const int n, const int n_2x1, const int n_1x1) { |
static KLSK_INLINE uint32_t to_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}; |
constexpr int offset[8] = {0, 15, 41, 74, 110, 145, 175, 196}; |
||||
return offset[n] + (15 - n * 2) * n_2x1 + n_1x1; |
return offset[n] + (15 - n * 2) * n_2x1 + n_1x1; |
||||
} |
} |
||||
|
|
||||
static uint32_t common_code_to_type_id(const uint64_t common_code) { |
uint32_t GroupUnion::type_id(const CommonCode common_code) { |
||||
const auto range = static_cast<uint32_t>(common_code); |
const auto range = static_cast<uint32_t>(common_code.unwrap()); |
||||
const auto n_1x1 = std::popcount((range >> 1) & range & 0x55555555); |
const auto n_1x1 = std::popcount((range >> 1) & range & 0x55555555); |
||||
const auto n_2x1 = 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); |
return to_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) { |
uint32_t GroupUnion::type_id(const RawCode raw_code) { |
||||
return raw_code_to_type_id(raw_code.unwrap()); |
const auto code = raw_code.unwrap(); |
||||
|
const auto n = std::popcount(((code >> 1) ^ code) & 0x0249249249249249); |
||||
|
const auto n_2x1 = std::popcount((code >> 1) & ~code & 0x0249249249249249); |
||||
|
const auto n_1x1 = std::popcount((code >> 1) & code & 0x0249249249249249) - n - 3; |
||||
|
return to_type_id(n, n_2x1, n_1x1); |
||||
} |
} |
||||
|
|
||||
klotski::cases::RangesUnion klotski::cases::GroupUnion::cases() const { |
klotski::cases::RangesUnion GroupUnion::cases() const { |
||||
Ranges ranges {}; |
|
||||
|
|
||||
auto [n, n_2x1, n_1x1] = BLOCK_NUM[type_id_]; |
auto [n, n_2x1, n_1x1] = BLOCK_NUM[type_id_]; |
||||
|
auto [s_a, s_b, s_c, s_d] = GROUP_UNION_CASES_NUM[type_id_]; |
||||
|
|
||||
// int n = TYPE_ID_N_NUM[type_id_];
|
Ranges ranges {}; |
||||
// int n_2x1 = TYPE_ID_N_2x1_NUM[type_id_];
|
ranges.reserve(BASIC_RANGES_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); |
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(); |
ranges.reverse(); |
||||
|
|
||||
// auto do_assert = [](uint32_t lhs, uint32_t rhs) {
|
|
||||
// if (lhs != rhs) {
|
|
||||
// std::cout << "error" << std::endl;
|
|
||||
// }
|
|
||||
// };
|
|
||||
|
|
||||
RangesUnion cases; |
RangesUnion cases; |
||||
|
cases[0x0].reserve(s_a); cases[0x1].reserve(s_b); cases[0x2].reserve(s_a); |
||||
// cases[0x0].reserve(7815);
|
cases[0x4].reserve(s_c); cases[0x5].reserve(s_d); cases[0x6].reserve(s_c); |
||||
// cases[0x1].reserve(6795);
|
cases[0x8].reserve(s_c); cases[0x9].reserve(s_d); cases[0xA].reserve(s_c); |
||||
// cases[0x2].reserve(7815);
|
cases[0xC].reserve(s_a); cases[0xD].reserve(s_b); cases[0xE].reserve(s_a); |
||||
//
|
|
||||
// cases[0x4].reserve(3525);
|
RANGE_DERIVE(0x0); RANGE_DERIVE(0x1); RANGE_DERIVE(0x2); |
||||
// cases[0x5].reserve(3465);
|
RANGE_DERIVE(0x4); RANGE_DERIVE(0x5); RANGE_DERIVE(0x6); |
||||
// cases[0x6].reserve(3525);
|
RANGE_DERIVE(0x8); RANGE_DERIVE(0x9); RANGE_DERIVE(0xA); |
||||
//
|
RANGE_DERIVE(0xC); RANGE_DERIVE(0xD); RANGE_DERIVE(0xE); |
||||
// 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; |
return cases; |
||||
} |
} |
||||
|
Loading…
Reference in new issue