diff --git a/src/fast_cal/cal_core.cc b/src/fast_cal/cal_core.cc index d2e1712..4380aed 100644 --- a/src/fast_cal/cal_core.cc +++ b/src/fast_cal/cal_core.cc @@ -37,8 +37,8 @@ void FastCal::new_case(uint64_t code, uint64_t mask) { } /// build total search tree -void FastCal::build(const RawCode &code) { - auto core = init((uint64_t)code); +void FastCal::build() { + auto core = init(root); /// start BFS search while (!cache.empty()) { core.next_cases(cache.front()->code, cache.front()->mask); @@ -47,8 +47,8 @@ void FastCal::build(const RawCode &code) { } /// found first matched target -RawCode FastCal::target(const RawCode &code, const match_t &match) { - auto core = init((uint64_t)code); +RawCode FastCal::target(const match_t &match) { + auto core = init(root); /// start BFS search while (!cache.empty()) { if (match(cache.front()->code)) { @@ -60,47 +60,47 @@ RawCode FastCal::target(const RawCode &code, const match_t &match) { return FC_NOT_FOUND; // target not found } -/// found multi-targets matched in first same layer -std::vector FastCal::target_multi(const RawCode &code, const match_t &match) { - auto core = init((uint64_t)code); +/// found all of the furthest cases +std::vector FastCal::furthest() { + auto core = init(root); auto layer_end = cache.back(); - std::vector matched; // matched list + std::vector layer_cases; /// start BFS search while (!cache.empty()) { - if (match(cache.front()->code)) { // match target - matched.emplace_back(cache.front()->code); - } core.next_cases(cache.front()->code, cache.front()->mask); + layer_cases.emplace_back( + RawCode::unsafe_create(cache.front()->code) // record layer cases + ); if (cache.front() == layer_end) { // reach layer ending - if (!matched.empty()) { - return matched; // stop at first matched layer + if (cache.size() == 1) { + break; // stop loop at last layer } + layer_cases.clear(); layer_end = cache.back(); // reset layer ending } cache.pop(); } - return std::vector{}; // no target found + return layer_cases; // release the latest layer cases } -/// found all of the furthest cases -std::vector FastCal::furthest(const RawCode &code) { - auto core = init((uint64_t)code); +/// found multi-targets matched in first same layer +std::vector FastCal::target_multi(const FastCal::match_t &match) { + auto core = init(root); auto layer_end = cache.back(); - std::vector layer_cases; + std::vector matched; // matched list /// start BFS search while (!cache.empty()) { + if (match(cache.front()->code)) { // match target + matched.emplace_back(cache.front()->code); + } core.next_cases(cache.front()->code, cache.front()->mask); - layer_cases.emplace_back( - RawCode::unsafe_create(cache.front()->code) // record layer cases - ); if (cache.front() == layer_end) { // reach layer ending - if (cache.size() == 1) { - break; // stop loop at last layer + if (!matched.empty()) { + return matched; // stop at first matched layer } - layer_cases.clear(); layer_end = cache.back(); // reset layer ending } cache.pop(); } - return layer_cases; // release latest layer cases + return std::vector{}; // no target found } diff --git a/src/fast_cal/fast_cal.cc b/src/fast_cal/fast_cal.cc index 9598786..1ea6fd2 100644 --- a/src/fast_cal/fast_cal.cc +++ b/src/fast_cal/fast_cal.cc @@ -4,17 +4,25 @@ #include "fast_cal.h" #include "raw_code.h" +FastCal::FastCal(const RawCode &code) { + this->root = (uint64_t)code; +} + +void FastCal::set_root(const RawCode &code) { + this->root = (uint64_t)code; +} + /// klotski resolved -> 2x2 block at address 13 (aka 0xD) auto resolved = [](uint64_t code) { return ((code >> (3 * 0xD)) & 0b111) == B_2x2; // check 2x2 block address }; -RawCode FastCal::solve(const RawCode &code) { - return FastCal::target(code, resolved); +RawCode FastCal::solve() { + return FastCal::target(resolved); } -std::vector FastCal::solve_multi(const RawCode &code) { - return FastCal::target_multi(code, resolved); +std::vector FastCal::solve_multi() { + return FastCal::target_multi(resolved); } std::vector FastCal::resolve(const RawCode &start) { @@ -56,17 +64,17 @@ std::vector FastCal::backtrack(const RawCode &code) { /// static BFS search functions std::vector> FastCal::to_furthest(const RawCode &start) { - auto fc = FastCal(); + auto fc = FastCal(start); std::vector> result; - for (const auto &furthest : fc.furthest(start)) { + for (const auto &furthest : fc.furthest()) { result.emplace_back(fc.backtrack(furthest)); // backtrack every furthest cases } return result; } std::vector FastCal::search(const RawCode &start, const match_t &match) { - auto fc = FastCal(); - auto result = fc.target(start, match); + auto fc = FastCal(start); + auto result = fc.target(match); if (result == FC_NOT_FOUND) { return std::vector{}; // target not matched } @@ -74,9 +82,9 @@ std::vector FastCal::search(const RawCode &start, const match_t &match) } std::vector> FastCal::search_multi(const RawCode &start, const match_t &match) { - auto fc = FastCal(); + auto fc = FastCal(start); std::vector> result; - for (const auto &target : fc.target_multi(start, match)) { + for (const auto &target : fc.target_multi(match)) { result.emplace_back(fc.backtrack(target)); // backtrack every target } return result; diff --git a/src/fast_cal/fast_cal.h b/src/fast_cal/fast_cal.h index 1835aed..6967386 100644 --- a/src/fast_cal/fast_cal.h +++ b/src/fast_cal/fast_cal.h @@ -15,19 +15,21 @@ class FastCal { public: typedef std::function match_t; + /// FastCal start case + void set_root(const RawCode &code); + explicit FastCal(const RawCode &code); + /// backtrack functions int step_num(const RawCode &code); std::vector backtrack(const RawCode &code); - // TODO: should we using code as class member - /// BFS search functions - void build(const RawCode &code); - RawCode solve(const RawCode &code); - std::vector furthest(const RawCode &code); - std::vector solve_multi(const RawCode &code); - RawCode target(const RawCode &code, const match_t &match); - std::vector target_multi(const RawCode &code, const match_t &match); + void build(); + RawCode solve(); + std::vector furthest(); + std::vector solve_multi(); + RawCode target(const match_t &match); + std::vector target_multi(const match_t &match); /// static BFS search functions static std::vector resolve(const RawCode &start); @@ -43,6 +45,7 @@ private: fast_cal_t *last; }; + uint64_t root; std::queue cache; std::unordered_map cases; diff --git a/src/main.cc b/src/main.cc index 71aa55b..9bc5837 100644 --- a/src/main.cc +++ b/src/main.cc @@ -17,55 +17,50 @@ int main() { BasicRanges::build(); -// std::vector test_cases; -// { -// AllCases::build(); -// std::vector all_cases; -// for (uint64_t head = 0; head < 16; ++head) { -// for (const auto &range : AllCases::fetch()[head]) { -// all_cases.emplace_back(head << 32 | range); -// } -// } -// for (uint32_t i = 0; i < 1000; ++i) { -// test_cases.emplace_back( -// RawCode::from_common_code(all_cases.at(i * 29334)) -// ); -// } -// } -// std::cout << "test size -> " << test_cases.size() << std::endl; + std::vector test_cases; + { + AllCases::build(); + std::vector all_cases; + for (uint64_t head = 0; head < 16; ++head) { + for (const auto &range : AllCases::fetch()[head]) { + all_cases.emplace_back(head << 32 | range); + } + } + for (uint32_t i = 0; i < 1000; ++i) { + test_cases.emplace_back( + RawCode::from_common_code(all_cases.at(i * 29334)) + ); + } + } + std::cout << "test size -> " << test_cases.size() << std::endl; // std::cout << "wait 3s" << std::endl; // sleep(3); -// std::cout << "start benchmark" << std::endl; + std::cout << "start benchmark" << std::endl; auto start_time = clock(); // AllCases::build(); -// { -// auto fc = FastCal(); -// for (uint32_t i = 0; i < test_cases.size(); ++i) { -// fc.solve(test_cases[i]); -// if (i % 1000 == 0) { -// std::cout << (i * 100 / test_cases.size()) << "%" << std::endl; -// } -// } -// for (auto code : test_cases) { -// fc.solve(code); -// } -// } + { + auto fc = FastCal(RawCode::unsafe_create(0)); + for (auto code : test_cases) { + fc.set_root(code); + fc.solve(); + } + } - auto a = Analyse(); +// auto a = Analyse(); // a.build((uint64_t)RawCode::from_common_code("1a9bf0c")); - auto ret = a.build_until((uint64_t)RawCode::from_common_code("1a9bf0c"), [](uint64_t code) { - return ((code >> (3 * 0xD)) & 0b111) == B_2x2; - }); - for (const auto &r : ret) { - std::cout << RawCode(r) << std::endl; - } +// auto ret = a.build_until((uint64_t)RawCode::from_common_code("1a9bf0c"), [](uint64_t code) { +// return ((code >> (3 * 0xD)) & 0b111) == B_2x2; +// }); +// for (const auto &r : ret) { +// std::cout << RawCode(r) << std::endl; +// } // auto raw_code = CommonCode("A5D3AF0").to_raw_code().unwrap(); @@ -104,11 +99,11 @@ int main() { // std::cout << CommonCode::from_short_code("AXCZN") << std::endl; -// std::cerr << (clock() - start_time) / CLOCKS_PER_SEC << "s" << std::endl; + std::cerr << (clock() - start_time) / CLOCKS_PER_SEC << "s" << std::endl; // std::cerr << (clock() - start_time) * 1000 / CLOCKS_PER_SEC << "ms" << std::endl; - std::cerr << (clock() - start_time) * 1000000 / CLOCKS_PER_SEC << "us" << std::endl; +// std::cerr << (clock() - start_time) * 1000000 / CLOCKS_PER_SEC << "us" << std::endl; -// std::cout << "complete benchmark" << std::endl; + std::cout << "complete benchmark" << std::endl; // pause();