mirror of https://github.com/dnomd343/klotski.git
Dnomd343
5 months ago
11 changed files with 173 additions and 64 deletions
@ -0,0 +1,16 @@ |
|||
#pragma once |
|||
|
|||
#include <array> |
|||
|
|||
namespace klotski::cases { |
|||
|
|||
// TODO: should we try to compress it?
|
|||
constexpr auto GROUP_SIZE = std::to_array<uint32_t>({ |
|||
#include "sizes.inc" |
|||
}); |
|||
|
|||
constexpr auto GROUP_SEED = std::to_array<uint64_t>({ |
|||
#include "seeds.inc" |
|||
}); |
|||
|
|||
} // namespace klotski::cases
|
File diff suppressed because one or more lines are too long
@ -1,45 +1,59 @@ |
|||
#include <absl/container/flat_hash_map.h> |
|||
|
|||
#include "core/core.h" |
|||
#include "group/group.h" |
|||
|
|||
#include <queue> |
|||
using klotski::core::Core; |
|||
using klotski::cases::Group; |
|||
using klotski::codec::RawCode; |
|||
using klotski::codec::CommonCode; |
|||
using klotski::cases::RangesUnion; |
|||
|
|||
#include <absl/container/btree_set.h> |
|||
#include <absl/container/flat_hash_map.h> |
|||
#include <absl/container/node_hash_map.h> |
|||
std::vector<RawCode> Group::extend(RawCode raw_code, uint32_t reserve) { |
|||
std::vector<RawCode> codes; |
|||
absl::flat_hash_map<uint64_t, uint64_t> cases; // <code, mask>
|
|||
reserve = reserve ? reserve : GroupUnion::from_raw_code(raw_code).max_group_size(); |
|||
codes.reserve(reserve); |
|||
cases.reserve(reserve); |
|||
|
|||
auto core = Core([&codes, &cases](uint64_t code, uint64_t mask) { |
|||
if (const auto match = cases.find(code); match != cases.end()) { |
|||
match->second |= mask; // update mask
|
|||
return; |
|||
} |
|||
cases.emplace(code, mask); |
|||
codes.emplace_back(RawCode::unsafe_create(code)); // new case
|
|||
}); |
|||
|
|||
uint64_t offset = 0; |
|||
codes.emplace_back(raw_code); |
|||
cases.emplace(raw_code, 0); // without mask
|
|||
while (offset != codes.size()) { |
|||
auto curr = codes[offset++].unwrap(); |
|||
core.next_cases(curr, cases.find(curr)->second); |
|||
} |
|||
return codes; |
|||
} |
|||
|
|||
#include <core/core.h> |
|||
RangesUnion Group::cases() const { |
|||
auto seed = CommonCode::unsafe_create(GROUP_SEED[flat_id()]); |
|||
|
|||
std::vector<uint64_t> klotski::cases::Group::extend(codec::RawCode raw_code) { |
|||
// std::cout << seed << std::endl;
|
|||
|
|||
auto max_size = GroupUnion::from_raw_code(raw_code).max_group_size(); |
|||
// auto max_size = GroupUnion::create(raw_code_to_type_id(raw_code))->max_group_size();
|
|||
auto codes = extend(seed.to_raw_code(), size()); |
|||
|
|||
uint64_t offset = 0; |
|||
std::vector<uint64_t> results; |
|||
results.reserve(max_size); |
|||
results.emplace_back(raw_code); |
|||
// std::cout << codes.size() << std::endl;
|
|||
|
|||
absl::flat_hash_map<uint64_t, uint64_t> cases; // <code, mask>
|
|||
cases.reserve(max_size); |
|||
cases.emplace(raw_code, 0); // without mask
|
|||
// TODO: how to reserve
|
|||
|
|||
auto core = klotski::core::Core( |
|||
[&results, &cases](auto code, auto mask) { // callback function
|
|||
auto current = cases.find(code); |
|||
if (current != cases.end()) { |
|||
current->second |= mask; // update mask
|
|||
return; |
|||
} |
|||
cases.emplace(code, mask); |
|||
results.emplace_back(code); |
|||
} |
|||
); |
|||
RangesUnion data; |
|||
|
|||
while (offset != results.size()) { |
|||
auto tmp = results[offset]; |
|||
core.next_cases(tmp, cases.find(tmp)->second); |
|||
++offset; |
|||
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)); |
|||
} |
|||
|
|||
return results; |
|||
// TODO: do sort process
|
|||
|
|||
return data; |
|||
} |
|||
|
@ -1,5 +1,34 @@ |
|||
#pragma once |
|||
|
|||
#include "constant/group.h" |
|||
|
|||
namespace klotski::cases { |
|||
|
|||
inline uint32_t Group::size() const { |
|||
return GROUP_SIZE[flat_id()]; |
|||
} |
|||
|
|||
inline uint32_t Group::flat_id() const { |
|||
return GROUP_OFFSET[type_id_] + group_id_; |
|||
} |
|||
|
|||
inline uint32_t Group::type_id() const { |
|||
return type_id_; |
|||
} |
|||
|
|||
inline uint32_t Group::group_id() const { |
|||
return group_id_; |
|||
} |
|||
|
|||
inline Group Group::unsafe_create(const uint32_t type_id, const uint32_t group_id) { |
|||
return std::bit_cast<Group>(static_cast<uint64_t>(group_id) << 32 | type_id); |
|||
} |
|||
|
|||
inline std::optional<Group> Group::create(const uint32_t type_id, const uint32_t group_id) { |
|||
if (type_id < TYPE_ID_LIMIT && group_id < GROUP_NUM[type_id]) { |
|||
return unsafe_create(type_id, group_id); |
|||
} |
|||
return std::nullopt; |
|||
} |
|||
|
|||
} // namespace klotski::cases |
|||
|
Loading…
Reference in new issue