Browse Source

refactor: using `RawCode` instead of `uint64_t`

master
Dnomd343 3 weeks ago
parent
commit
5133793cb9
  1. 2
      src/core/CMakeLists.txt
  2. 11
      src/core/fast_cal/fast_cal.h
  3. 48
      src/core/fast_cal/internal/fast_cal.cc
  4. 18
      src/core/fast_cal/internal/fast_cal.inl
  5. 16
      src/core/group/internal/extend.cc
  6. 14
      src/core/main.cc
  7. 6
      src/core/mover/internal/mover.cc
  8. 6
      src/core/mover/mover.h

2
src/core/CMakeLists.txt

@ -20,7 +20,7 @@ set(KLOTSKI_CORE_SRC
mover/internal/mover.cc
fast_cal/internal/demo.cc
fast_cal/internal/fast_cal.cc
group/internal/group_union.cc
group/internal/extend.cc

11
src/core/fast_cal/fast_cal.h

@ -8,7 +8,6 @@
#include <cstdint>
#include <functional>
#include "group/group.h"
#include "mover/mover.h"
#include "layer_queue.h"
#include "raw_code/raw_code.h"
@ -27,6 +26,8 @@ public:
// TODO: add global build
void build();
/// Calculate a minimum-step case.
std::optional<codec::RawCode> solve();
@ -56,18 +57,20 @@ private:
KLSK_INLINE void spawn_next(mover::MaskMover &mover);
/// Try to emplace the searched info into the cache.
KLSK_INLINE bool try_emplace(uint64_t code, uint64_t mask);
KLSK_INLINE bool try_emplace(codec::RawCode code, uint64_t mask);
// ------------------------------------------------------------------------------------- //
// TODO: add invalid RawCode constexpr var
struct data_t {
uint64_t mask;
uint64_t back;
codec::RawCode back;
};
// codec::RawCode root_;
LayerQueue<codec::RawCode> codes_;
phmap::flat_hash_map<uint64_t, data_t> cases_;
phmap::flat_hash_map<codec::RawCode, data_t> cases_;
// ------------------------------------------------------------------------------------- //
};

48
src/core/fast_cal/internal/demo.cc → src/core/fast_cal/internal/fast_cal.cc

@ -1,11 +1,6 @@
#include "fast_cal/fast_cal.h"
#include <iostream>
#include <parallel_hashmap/phmap.h>
#include "mover/mover.h"
#include "group/group.h"
#include "fast_cal/fast_cal.h"
using klotski::codec::RawCode;
using klotski::codec::CommonCode;
@ -16,8 +11,8 @@ using klotski::cases::GroupUnion;
using klotski::fast_cal::FastCalPro;
static KLSK_INLINE bool is_solved(uint64_t raw_code) {
return ((raw_code >> 39) & 0b111) == 0b100;
static KLSK_INLINE bool is_solved(RawCode raw_code) {
return ((raw_code.unwrap() >> 39) & 0b111) == 0b100;
}
std::optional<RawCode> FastCalPro::solve() {
@ -26,9 +21,9 @@ std::optional<RawCode> FastCalPro::solve() {
// }
uint64_t solution = 0;
auto mover = MaskMover([this, &solution](uint64_t code, uint64_t mask) {
auto mover = MaskMover([this, &solution](RawCode code, uint64_t mask) {
if (try_emplace(code, mask) && is_solved(code)) {
solution = code;
solution = code.unwrap();
}
});
while (!codes_.is_ending()) {
@ -44,9 +39,9 @@ std::optional<RawCode> FastCalPro::search(std::function<bool(RawCode)> &&match)
// TODO: check root case
uint64_t target = 0;
auto mover = MaskMover([this, &target, match = std::move(match)](uint64_t code, uint64_t mask) {
if (try_emplace(code, mask) && match(RawCode::unsafe_create(code))) {
target = code;
auto mover = MaskMover([this, &target, match = std::move(match)](RawCode code, uint64_t mask) {
if (try_emplace(code, mask) && match(code)) {
target = code.unwrap();
}
});
while (!codes_.is_ending()) {
@ -64,17 +59,16 @@ std::vector<RawCode> FastCalPro::solve_multi() {
bool stop_flag = false;
std::vector<RawCode> results {};
auto mover = MaskMover([this, &stop_flag, &results](uint64_t code, uint64_t mask) {
auto mover = MaskMover([this, &stop_flag, &results](RawCode code, uint64_t mask) {
if (try_emplace(code, mask) && is_solved(code)) {
stop_flag = true;
results.emplace_back(RawCode::unsafe_create(code));
results.emplace_back(code);
}
});
while (!codes_.is_ending()) {
spawn_next(mover);
if (codes_.is_new_layer() && stop_flag) {
// TODO: fix when solutions at last layer
if (stop_flag && (codes_.is_new_layer() || codes_.is_ending())) {
return results;
}
@ -82,26 +76,30 @@ std::vector<RawCode> FastCalPro::solve_multi() {
return {};
}
std::vector<RawCode> FastCalPro::furthest() {
auto mover = MaskMover([this](uint64_t code, uint64_t mask) {
void FastCalPro::build() {
auto mover = MaskMover([this](RawCode code, uint64_t mask) {
try_emplace(code, mask);
});
while (true) {
while (!codes_.is_ending()) {
spawn_next(mover);
if (codes_.is_ending()) {
return codes_.last_layer();
}
}
}
std::vector<RawCode> FastCalPro::furthest() {
if (!codes_.is_ending()) {
build();
}
return codes_.last_layer();
}
std::vector<RawCode> FastCalPro::backtrack(RawCode code) const {
if (const auto match = cases_.find(code.unwrap()); match == cases_.end()) {
if (const auto match = cases_.find(code); match == cases_.end()) {
return {}; // case not found
}
std::vector<RawCode> path;
while (code != 0) {
path.emplace_back(code);
code = RawCode::unsafe_create(cases_.find(code.unwrap())->second.back);
code = cases_.find(code)->second.back;
}
std::reverse(path.begin(), path.end());
return path;

18
src/core/fast_cal/internal/fast_cal.inl

@ -1,30 +1,32 @@
#pragma once
#include "group/group.h"
namespace klotski::fast_cal {
inline FastCalPro::FastCalPro(codec::RawCode raw_code) : codes_({raw_code}, cases::GroupUnion::from_raw_code(raw_code).max_group_size()) {
auto reserve = cases::GroupUnion::from_raw_code(raw_code).max_group_size();
// cases_.reserve(static_cast<size_t>(25955 * 1.56));
inline FastCalPro::FastCalPro(codec::RawCode raw_code)
: codes_({raw_code}, cases::GroupUnion::from_raw_code(raw_code).max_group_size()) {
const auto reserve = cases::GroupUnion::from_raw_code(raw_code).max_group_size();
cases_.reserve(static_cast<size_t>(reserve * 1.56));
cases_.emplace(raw_code, data_t {0, 0}); // without mask
cases_.emplace(raw_code, data_t {0, codec::RawCode::unsafe_create(0)}); // without mask
}
inline KLSK_INLINE bool FastCalPro::try_emplace(uint64_t code, uint64_t mask) {
inline KLSK_INLINE bool FastCalPro::try_emplace(codec::RawCode code, uint64_t mask) {
if (const auto match = cases_.find(code); match != cases_.end()) {
match->second.mask |= mask; // update mask
return false;
}
cases_.emplace(code, data_t {
.mask = mask,
.back = codes_.current().unwrap(),
.back = codes_.current(),
});
codes_.emplace(codec::RawCode::unsafe_create(code));
codes_.emplace(code);
return true;
}
inline KLSK_INLINE void FastCalPro::spawn_next(mover::MaskMover &mover) {
auto curr = codes_.current();
mover.next_cases(curr.unwrap(), cases_.find(curr.unwrap())->second.mask);
mover.next_cases(curr, cases_.find(curr)->second.mask);
codes_.next();
}

16
src/core/group/internal/extend.cc

@ -24,13 +24,13 @@ std::vector<RawCode> klotski::cases::Group_extend(RawCode raw_code, uint32_t res
codes.reserve(GroupUnion::from_raw_code(raw_code).max_group_size());
cases.reserve(25955 * 1.56);
auto core = MaskMover([&codes, &cases](uint64_t code, uint64_t mask) {
if (const auto match = cases.find(code); match != cases.end()) {
auto core = MaskMover([&codes, &cases](RawCode code, uint64_t mask) {
if (const auto match = cases.find(code.unwrap()); match != cases.end()) {
match->second |= mask; // update mask
return;
}
cases.emplace(code, mask);
codes.emplace_back(RawCode::unsafe_create(code)); // new case
codes.emplace_back(code); // new case
});
uint64_t offset = 0;
@ -38,7 +38,7 @@ std::vector<RawCode> klotski::cases::Group_extend(RawCode raw_code, uint32_t res
cases.emplace(raw_code, 0); // without mask
while (offset != codes.size()) {
auto curr = codes[offset++].unwrap();
core.next_cases(curr, cases.find(curr)->second);
core.next_cases(RawCode::unsafe_create(curr), cases.find(curr)->second);
}
// std::cout << cases.size() << std::endl;
// std::cout << cases.load_factor() << std::endl;
@ -52,13 +52,13 @@ double klotski::cases::Group_load_factor(RawCode raw_code, double coff) {
codes.reserve(reserve);
cases.reserve(static_cast<size_t>(coff * reserve));
auto core = MaskMover([&codes, &cases](uint64_t code, uint64_t mask) {
if (const auto match = cases.find(code); match != cases.end()) {
auto core = MaskMover([&codes, &cases](RawCode code, uint64_t mask) {
if (const auto match = cases.find(code.unwrap()); match != cases.end()) {
match->second |= mask; // update mask
return;
}
cases.emplace(code, mask);
codes.emplace_back(RawCode::unsafe_create(code)); // new case
codes.emplace_back(code); // new case
});
uint64_t offset = 0;
@ -66,7 +66,7 @@ double klotski::cases::Group_load_factor(RawCode raw_code, double coff) {
cases.emplace(raw_code, 0); // without mask
while (offset != codes.size()) {
auto curr = codes[offset++].unwrap();
core.next_cases(curr, cases.find(curr)->second);
core.next_cases(RawCode::unsafe_create(curr), cases.find(curr)->second);
}
// if (cases.size() != reserve) {

14
src/core/main.cc

@ -14,6 +14,8 @@
#include "short_code/short_code.h"
#include "common_code/common_code.h"
#include <parallel_hashmap/phmap.h>
#include "../../third_party/thread-pool/include/BS_thread_pool.hpp"
using klotski::mover::MaskMover;
@ -49,7 +51,7 @@ int main() {
auto code = CommonCode::unsafe_create(0x1A9BF0C00).to_raw_code();
klotski::fast_cal::FastCalPro fc {code};
// std::cout << fc.solve().value() << std::endl;
std::cout << fc.solve().value() << std::endl;
// for (auto x : fc.solve_multi()) {
// std::cout << x << std::endl;
@ -59,11 +61,11 @@ int main() {
// std::cout << x.to_common_code() << std::endl;
// }
fc.furthest();
for (const auto &layer : fc.exports()) {
std::cout << layer.size() << std::endl;
}
std::cout << "layer num: " << fc.exports().size() << std::endl;
// fc.furthest();
// for (const auto &layer : fc.exports()) {
// std::cout << layer.size() << std::endl;
// }
// std::cout << "layer num: " << fc.exports().size() << std::endl;
// for (int i = 0; i < 10000000; ++i) {
// MaskMover mover([](uint64_t code, uint64_t mask) {

6
src/core/mover/internal/mover.cc

@ -73,6 +73,7 @@
///////////////////////////////////////////////
using klotski::codec::RawCode;
using klotski::mover::MaskMover;
inline void MaskMover::cache_insert(cache_t next_case) { // try to insert into cache
@ -162,7 +163,8 @@ void MaskMover::move_2x2(uint64_t code, int addr) { // try to move target 2x2 bl
}
}
void MaskMover::next_cases(uint64_t code, uint64_t mask) { // search next step cases
void MaskMover::next_cases(RawCode raw_code, uint64_t mask) { // search next step cases
const uint64_t code = raw_code.unwrap();
cache_[0].filter = 0; // without filter
cache_[0].code = code; // bfs root code
auto range = code | mask;
@ -186,7 +188,7 @@ void MaskMover::next_cases(uint64_t code, uint64_t mask) { // search next step c
}
if (cache_size_ != 1) { // found one or more next cases
for (int i = 1; i < cache_size_; ++i) {
release_(cache_[i].code, cache_[i].mask); // release next cases
release_(RawCode::unsafe_create(cache_[i].code), cache_[i].mask); // release next cases
}
cache_size_ = 1; // reset cache size
}

6
src/core/mover/mover.h

@ -61,6 +61,8 @@
#include <utility>
#include <functional>
#include "raw_code/raw_code.h"
namespace klotski::mover {
// TODO: new version without mask
@ -70,10 +72,10 @@ namespace klotski::mover {
class MaskMover {
public:
/// Release with code and mask
typedef std::function<void(uint64_t, uint64_t)> release_t;
typedef std::function<void(codec::RawCode, uint64_t)> release_t;
/// Core interface
void next_cases(uint64_t code, uint64_t mask);
void next_cases(codec::RawCode code, uint64_t mask);
explicit MaskMover(release_t release_func) : release_(std::move(release_func)) {}
private:

Loading…
Cancel
Save