mirror of https://github.com/dnomd343/klotski.git
Dnomd343
7 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 "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> |
std::vector<RawCode> Group::extend(RawCode raw_code, uint32_t reserve) { |
||||
#include <absl/container/flat_hash_map.h> |
std::vector<RawCode> codes; |
||||
#include <absl/container/node_hash_map.h> |
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 codes = extend(seed.to_raw_code(), size()); |
||||
// auto max_size = GroupUnion::create(raw_code_to_type_id(raw_code))->max_group_size();
|
|
||||
|
|
||||
uint64_t offset = 0; |
// std::cout << codes.size() << std::endl;
|
||||
std::vector<uint64_t> results; |
|
||||
results.reserve(max_size); |
|
||||
results.emplace_back(raw_code); |
|
||||
|
|
||||
absl::flat_hash_map<uint64_t, uint64_t> cases; // <code, mask>
|
// TODO: how to reserve
|
||||
cases.reserve(max_size); |
|
||||
cases.emplace(raw_code, 0); // without mask
|
|
||||
|
|
||||
auto core = klotski::core::Core( |
RangesUnion data; |
||||
[&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); |
|
||||
} |
|
||||
); |
|
||||
|
|
||||
while (offset != results.size()) { |
for (auto raw_code : codes) { |
||||
auto tmp = results[offset]; |
auto common_code = raw_code.to_common_code().unwrap(); |
||||
core.next_cases(tmp, cases.find(tmp)->second); |
data[common_code >> 32].emplace_back(static_cast<uint32_t>(common_code)); |
||||
++offset; |
|
||||
} |
} |
||||
|
|
||||
return results; |
// TODO: do sort process
|
||||
|
|
||||
|
return data; |
||||
} |
} |
||||
|
@ -1,5 +1,34 @@ |
|||||
#pragma once |
#pragma once |
||||
|
|
||||
|
#include "constant/group.h" |
||||
|
|
||||
namespace klotski::cases { |
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 |
} // namespace klotski::cases |
||||
|
Loading…
Reference in new issue