diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 65883b6..3183728 100644 --- a/src/core/CMakeLists.txt +++ b/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 diff --git a/src/core/fast_cal/fast_cal.h b/src/core/fast_cal/fast_cal.h index d392d27..a11b859 100644 --- a/src/core/fast_cal/fast_cal.h +++ b/src/core/fast_cal/fast_cal.h @@ -8,7 +8,6 @@ #include #include -#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 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 codes_; - phmap::flat_hash_map cases_; + phmap::flat_hash_map cases_; // ------------------------------------------------------------------------------------- // }; diff --git a/src/core/fast_cal/internal/demo.cc b/src/core/fast_cal/internal/fast_cal.cc similarity index 66% rename from src/core/fast_cal/internal/demo.cc rename to src/core/fast_cal/internal/fast_cal.cc index c78a16c..a118755 100644 --- a/src/core/fast_cal/internal/demo.cc +++ b/src/core/fast_cal/internal/fast_cal.cc @@ -1,11 +1,6 @@ -#include "fast_cal/fast_cal.h" - -#include - -#include - #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 FastCalPro::solve() { @@ -26,9 +21,9 @@ std::optional 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 FastCalPro::search(std::function &&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 FastCalPro::solve_multi() { bool stop_flag = false; std::vector 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 FastCalPro::solve_multi() { return {}; } -std::vector 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 FastCalPro::furthest() { + if (!codes_.is_ending()) { + build(); + } + return codes_.last_layer(); +} + std::vector 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 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; diff --git a/src/core/fast_cal/internal/fast_cal.inl b/src/core/fast_cal/internal/fast_cal.inl index eb99a9d..4aee075 100644 --- a/src/core/fast_cal/internal/fast_cal.inl +++ b/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(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(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(); } diff --git a/src/core/group/internal/extend.cc b/src/core/group/internal/extend.cc index 9b396fb..9c29515 100644 --- a/src/core/group/internal/extend.cc +++ b/src/core/group/internal/extend.cc @@ -24,13 +24,13 @@ std::vector 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 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(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) { diff --git a/src/core/main.cc b/src/core/main.cc index 5d59966..bdca255 100644 --- a/src/core/main.cc +++ b/src/core/main.cc @@ -14,6 +14,8 @@ #include "short_code/short_code.h" #include "common_code/common_code.h" +#include + #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) { diff --git a/src/core/mover/internal/mover.cc b/src/core/mover/internal/mover.cc index 4ce4906..e2c4281 100644 --- a/src/core/mover/internal/mover.cc +++ b/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 } diff --git a/src/core/mover/mover.h b/src/core/mover/mover.h index b2b3d3b..6badfd8 100644 --- a/src/core/mover/mover.h +++ b/src/core/mover/mover.h @@ -61,6 +61,8 @@ #include #include +#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 release_t; + typedef std::function 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: