Browse Source

perf: single target search

legacy
Dnomd343 2 years ago
parent
commit
d071cb7fc3
  1. 68
      src/fast_cal/fast_cal.cc
  2. 18
      src/fast_cal/fast_cal.h
  3. 8
      src/main.cc

68
src/fast_cal/fast_cal.cc

@ -7,7 +7,15 @@
#include <iostream> #include <iostream>
#include <algorithm> #include <algorithm>
Core FastCal::import_core() { Core FastCal::init() { // initialization process
/// clear working data
cases.clear();
std::queue<fast_cal_t*>{}.swap(cache);
// TODO: test the speed without hashmap reserve
cases.reserve(65536);
/// import klotski core
return Core( return Core(
[this](auto &&code, auto &&mask) { // lambda as function pointer [this](auto &&code, auto &&mask) { // lambda as function pointer
new_case(std::forward<decltype(code)>(code), std::forward<decltype(mask)>(mask)); new_case(std::forward<decltype(code)>(code), std::forward<decltype(mask)>(mask));
@ -16,31 +24,18 @@ Core FastCal::import_core() {
} }
void FastCal::new_case(uint64_t code, uint64_t mask) { // callback function for new case void FastCal::new_case(uint64_t code, uint64_t mask) { // callback function for new case
auto current = cases.find(code); auto current = cases.find(code);
if (current != cases.end()) { // find existed case if (current != cases.end()) { // find existed case
current->second.mask |= mask; // update mask info current->second.mask |= mask; // update mask info
return; return;
} }
cache.emplace(&cases.emplace(code, fast_cal_t { // record new case
cache.emplace(&cases.emplace(code, fast_cal_t {
.code = code, .code = code,
.mask = mask, .mask = mask,
.last = cache.front(), .last = cache.front(), // link parent case
}).first->second); }).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<uint64_t> FastCal::backtrack(uint64_t code) { std::vector<uint64_t> FastCal::backtrack(uint64_t code) {
std::vector<uint64_t> path; std::vector<uint64_t> path;
@ -57,44 +52,27 @@ std::vector<uint64_t> FastCal::backtrack(uint64_t code) {
} }
uint64_t FastCal::target(const std::function<bool(uint64_t)> &match) { uint64_t FastCal::solve(uint64_t code) {
return FastCal::target(code, [](uint64_t code) {
auto core = import_core(); return ((code >> (3 * 0xD)) & 0b111) == B_2x2; // check 2x2 block address
});
// clear data }
cases.clear();
std::queue<fast_cal_t*>{}.swap(cache);
// auto empty = std::queue<fast_cal_t*>{};
// std::swap(empty, cache);
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 { cache.emplace(&cases.emplace(code, fast_cal_t {
.code = root, .code = code,
.mask = 0, .mask = 0,
.last = nullptr, .last = nullptr, // without parent node
}).first->second); }).first->second);
while (!cache.empty()) { while (!cache.empty()) {
if (match(cache.front()->code)) { if (match(cache.front()->code)) {
break; return cache.front()->code; // match target
} }
core.next_cases(cache.front()->code, cache.front()->mask); core.next_cases(cache.front()->code, cache.front()->mask);
cache.pop(); cache.pop();
} }
return FastCal::NOT_FOUND; // target not found
std::cout << "size: " << cases.size() << std::endl;
// TODO: cache may empty -> never found
if (!cache.empty()) {
return cache.front()->code;
}
return FastCal::NOT_FOUND;
} }

18
src/fast_cal/fast_cal.h

@ -9,7 +9,9 @@
class FastCal { class FastCal {
public: public:
explicit FastCal(uint64_t code) : root(code) {} typedef std::function<bool(uint64_t)> check_t;
// explicit FastCal(uint64_t code) : root(code) {}
// search resolve // search resolve
// search all min-step resolve // search all min-step resolve
@ -19,17 +21,13 @@ public:
/// xxx_multi only search until same layer /// xxx_multi only search until same layer
// std::vector<uint64_t> solve(uint64_t code);
// std::vector<uint64_t> solve();
uint64_t solve();
// solve_multi // solve_multi
// std::vector<uint64_t> target(const std::function<bool(uint64_t)> &match); uint64_t solve(uint64_t code);
uint64_t target(const std::function<bool(uint64_t)> &match);
std::vector<uint64_t> 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<uint64_t> backtrack(uint64_t code);
// TODO: static search functions // TODO: static search functions
@ -43,12 +41,12 @@ private:
}; };
uint64_t root; // uint64_t root;
std::queue<fast_cal_t*> cache; std::queue<fast_cal_t*> cache;
std::unordered_map<uint64_t, fast_cal_t> cases; std::unordered_map<uint64_t, fast_cal_t> cases;
Core import_core(); Core init();
void new_case(uint64_t code, uint64_t mask); void new_case(uint64_t code, uint64_t mask);

8
src/main.cc

@ -25,11 +25,11 @@ int main() {
// AllCases::build(); // AllCases::build();
// auto f = FastCal(); auto f = FastCal();
// auto ret = f.solve(RawCode::from_common_code("1a9bf0c").unwrap()); auto ret = f.solve(RawCode::from_common_code("1a9bf0c").unwrap());
auto f = FastCal(RawCode::from_common_code("1a9bf0c").unwrap()); // auto f = FastCal(RawCode::from_common_code("1a9bf0c").unwrap());
auto ret = f.solve(); // auto ret = f.solve();
std::cout << RawCode(ret) << std::endl; std::cout << RawCode(ret) << std::endl;
// for (const auto &c : ret) { // for (const auto &c : ret) {

Loading…
Cancel
Save