diff --git a/src/fast_cal/fast_cal.cc b/src/fast_cal/fast_cal.cc index dbea396..9c128b6 100644 --- a/src/fast_cal/fast_cal.cc +++ b/src/fast_cal/fast_cal.cc @@ -7,7 +7,15 @@ #include #include -Core FastCal::import_core() { +Core FastCal::init() { // initialization process + /// clear working data + cases.clear(); + std::queue{}.swap(cache); + + // TODO: test the speed without hashmap reserve + cases.reserve(65536); + + /// import klotski core return Core( [this](auto &&code, auto &&mask) { // lambda as function pointer new_case(std::forward(code), std::forward(mask)); @@ -16,31 +24,18 @@ Core FastCal::import_core() { } void FastCal::new_case(uint64_t code, uint64_t mask) { // callback function for new case - auto current = cases.find(code); if (current != cases.end()) { // find existed case current->second.mask |= mask; // update mask info return; } - - cache.emplace(&cases.emplace(code, fast_cal_t { + cache.emplace(&cases.emplace(code, fast_cal_t { // record new case .code = code, .mask = mask, - .last = cache.front(), + .last = cache.front(), // link parent case }).first->second); - -} - -uint64_t FastCal::solve() { - - auto resolved = [](uint64_t code) { - return ((code >> (3 * 0xD)) & 0b111) == B_2x2; - }; - return target(resolved); - } -// TODO: single backtrack function std::vector FastCal::backtrack(uint64_t code) { std::vector path; @@ -57,44 +52,27 @@ std::vector FastCal::backtrack(uint64_t code) { } -uint64_t FastCal::target(const std::function &match) { - - auto core = import_core(); - - // clear data - cases.clear(); - - std::queue{}.swap(cache); - -// auto empty = std::queue{}; -// std::swap(empty, cache); +uint64_t FastCal::solve(uint64_t code) { + return FastCal::target(code, [](uint64_t code) { + return ((code >> (3 * 0xD)) & 0b111) == B_2x2; // check 2x2 block address + }); +} - cases.reserve(65536); +uint64_t FastCal::target(uint64_t code, const check_t &match) { + auto core = init(); - cache.emplace(&cases.emplace(root, fast_cal_t { - .code = root, + cache.emplace(&cases.emplace(code, fast_cal_t { + .code = code, .mask = 0, - .last = nullptr, + .last = nullptr, // without parent node }).first->second); while (!cache.empty()) { - if (match(cache.front()->code)) { - break; + return cache.front()->code; // match target } - core.next_cases(cache.front()->code, cache.front()->mask); cache.pop(); } - - std::cout << "size: " << cases.size() << std::endl; - - // TODO: cache may empty -> never found - if (!cache.empty()) { - - return cache.front()->code; - - } - return FastCal::NOT_FOUND; - + return FastCal::NOT_FOUND; // target not found } diff --git a/src/fast_cal/fast_cal.h b/src/fast_cal/fast_cal.h index 670eb8b..1bf2d3c 100644 --- a/src/fast_cal/fast_cal.h +++ b/src/fast_cal/fast_cal.h @@ -9,7 +9,9 @@ class FastCal { public: - explicit FastCal(uint64_t code) : root(code) {} + typedef std::function check_t; + +// explicit FastCal(uint64_t code) : root(code) {} // search resolve // search all min-step resolve @@ -19,17 +21,13 @@ public: /// xxx_multi only search until same layer -// std::vector solve(uint64_t code); -// std::vector solve(); - uint64_t solve(); // solve_multi -// std::vector target(const std::function &match); - uint64_t target(const std::function &match); + uint64_t solve(uint64_t code); - std::vector backtrack(uint64_t code); + uint64_t target(uint64_t code, const check_t &match); - // TODO: continue search process? -> reuse exist data (ensure working code not changed) + std::vector backtrack(uint64_t code); // TODO: static search functions @@ -43,12 +41,12 @@ private: }; - uint64_t root; +// uint64_t root; std::queue cache; std::unordered_map cases; - Core import_core(); + Core init(); void new_case(uint64_t code, uint64_t mask); diff --git a/src/main.cc b/src/main.cc index 592c8ab..d7cbf3c 100644 --- a/src/main.cc +++ b/src/main.cc @@ -25,11 +25,11 @@ int main() { // AllCases::build(); -// auto f = FastCal(); -// auto ret = f.solve(RawCode::from_common_code("1a9bf0c").unwrap()); + auto f = FastCal(); + auto ret = f.solve(RawCode::from_common_code("1a9bf0c").unwrap()); - auto f = FastCal(RawCode::from_common_code("1a9bf0c").unwrap()); - auto ret = f.solve(); +// auto f = FastCal(RawCode::from_common_code("1a9bf0c").unwrap()); +// auto ret = f.solve(); std::cout << RawCode(ret) << std::endl; // for (const auto &c : ret) {