Browse Source

update: root code as FastCal class member

legacy
Dnomd343 2 years ago
parent
commit
0581452846
  1. 50
      src/fast_cal/cal_core.cc
  2. 28
      src/fast_cal/fast_cal.cc
  3. 19
      src/fast_cal/fast_cal.h
  4. 73
      src/main.cc

50
src/fast_cal/cal_core.cc

@ -37,8 +37,8 @@ void FastCal::new_case(uint64_t code, uint64_t mask) {
} }
/// build total search tree /// build total search tree
void FastCal::build(const RawCode &code) { void FastCal::build() {
auto core = init((uint64_t)code); auto core = init(root);
/// start BFS search /// start BFS search
while (!cache.empty()) { while (!cache.empty()) {
core.next_cases(cache.front()->code, cache.front()->mask); core.next_cases(cache.front()->code, cache.front()->mask);
@ -47,8 +47,8 @@ void FastCal::build(const RawCode &code) {
} }
/// found first matched target /// found first matched target
RawCode FastCal::target(const RawCode &code, const match_t &match) { RawCode FastCal::target(const match_t &match) {
auto core = init((uint64_t)code); auto core = init(root);
/// start BFS search /// start BFS search
while (!cache.empty()) { while (!cache.empty()) {
if (match(cache.front()->code)) { 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 return FC_NOT_FOUND; // target not found
} }
/// found multi-targets matched in first same layer /// found all of the furthest cases
std::vector<RawCode> FastCal::target_multi(const RawCode &code, const match_t &match) { std::vector<RawCode> FastCal::furthest() {
auto core = init((uint64_t)code); auto core = init(root);
auto layer_end = cache.back(); auto layer_end = cache.back();
std::vector<RawCode> matched; // matched list std::vector<RawCode> layer_cases;
/// start BFS search /// start BFS search
while (!cache.empty()) { 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); 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.front() == layer_end) { // reach layer ending
if (!matched.empty()) { if (cache.size() == 1) {
return matched; // stop at first matched layer break; // stop loop at last layer
} }
layer_cases.clear();
layer_end = cache.back(); // reset layer ending layer_end = cache.back(); // reset layer ending
} }
cache.pop(); cache.pop();
} }
return std::vector<RawCode>{}; // no target found return layer_cases; // release the latest layer cases
} }
/// found all of the furthest cases /// found multi-targets matched in first same layer
std::vector<RawCode> FastCal::furthest(const RawCode &code) { std::vector<RawCode> FastCal::target_multi(const FastCal::match_t &match) {
auto core = init((uint64_t)code); auto core = init(root);
auto layer_end = cache.back(); auto layer_end = cache.back();
std::vector<RawCode> layer_cases; std::vector<RawCode> matched; // matched list
/// start BFS search /// start BFS search
while (!cache.empty()) { 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); 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.front() == layer_end) { // reach layer ending
if (cache.size() == 1) { if (!matched.empty()) {
break; // stop loop at last layer return matched; // stop at first matched layer
} }
layer_cases.clear();
layer_end = cache.back(); // reset layer ending layer_end = cache.back(); // reset layer ending
} }
cache.pop(); cache.pop();
} }
return layer_cases; // release latest layer cases return std::vector<RawCode>{}; // no target found
} }

28
src/fast_cal/fast_cal.cc

@ -4,17 +4,25 @@
#include "fast_cal.h" #include "fast_cal.h"
#include "raw_code.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) /// klotski resolved -> 2x2 block at address 13 (aka 0xD)
auto resolved = [](uint64_t code) { auto resolved = [](uint64_t code) {
return ((code >> (3 * 0xD)) & 0b111) == B_2x2; // check 2x2 block address return ((code >> (3 * 0xD)) & 0b111) == B_2x2; // check 2x2 block address
}; };
RawCode FastCal::solve(const RawCode &code) { RawCode FastCal::solve() {
return FastCal::target(code, resolved); return FastCal::target(resolved);
} }
std::vector<RawCode> FastCal::solve_multi(const RawCode &code) { std::vector<RawCode> FastCal::solve_multi() {
return FastCal::target_multi(code, resolved); return FastCal::target_multi(resolved);
} }
std::vector<RawCode> FastCal::resolve(const RawCode &start) { std::vector<RawCode> FastCal::resolve(const RawCode &start) {
@ -56,17 +64,17 @@ std::vector<RawCode> FastCal::backtrack(const RawCode &code) {
/// static BFS search functions /// static BFS search functions
std::vector<std::vector<RawCode>> FastCal::to_furthest(const RawCode &start) { std::vector<std::vector<RawCode>> FastCal::to_furthest(const RawCode &start) {
auto fc = FastCal(); auto fc = FastCal(start);
std::vector<std::vector<RawCode>> result; std::vector<std::vector<RawCode>> result;
for (const auto &furthest : fc.furthest(start)) { for (const auto &furthest : fc.furthest()) {
result.emplace_back(fc.backtrack(furthest)); // backtrack every furthest cases result.emplace_back(fc.backtrack(furthest)); // backtrack every furthest cases
} }
return result; return result;
} }
std::vector<RawCode> FastCal::search(const RawCode &start, const match_t &match) { std::vector<RawCode> FastCal::search(const RawCode &start, const match_t &match) {
auto fc = FastCal(); auto fc = FastCal(start);
auto result = fc.target(start, match); auto result = fc.target(match);
if (result == FC_NOT_FOUND) { if (result == FC_NOT_FOUND) {
return std::vector<RawCode>{}; // target not matched return std::vector<RawCode>{}; // target not matched
} }
@ -74,9 +82,9 @@ std::vector<RawCode> FastCal::search(const RawCode &start, const match_t &match)
} }
std::vector<std::vector<RawCode>> FastCal::search_multi(const RawCode &start, const match_t &match) { std::vector<std::vector<RawCode>> FastCal::search_multi(const RawCode &start, const match_t &match) {
auto fc = FastCal(); auto fc = FastCal(start);
std::vector<std::vector<RawCode>> result; std::vector<std::vector<RawCode>> 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 result.emplace_back(fc.backtrack(target)); // backtrack every target
} }
return result; return result;

19
src/fast_cal/fast_cal.h

@ -15,19 +15,21 @@ class FastCal {
public: public:
typedef std::function<bool(uint64_t)> match_t; typedef std::function<bool(uint64_t)> match_t;
/// FastCal start case
void set_root(const RawCode &code);
explicit FastCal(const RawCode &code);
/// backtrack functions /// backtrack functions
int step_num(const RawCode &code); int step_num(const RawCode &code);
std::vector<RawCode> backtrack(const RawCode &code); std::vector<RawCode> backtrack(const RawCode &code);
// TODO: should we using code as class member
/// BFS search functions /// BFS search functions
void build(const RawCode &code); void build();
RawCode solve(const RawCode &code); RawCode solve();
std::vector<RawCode> furthest(const RawCode &code); std::vector<RawCode> furthest();
std::vector<RawCode> solve_multi(const RawCode &code); std::vector<RawCode> solve_multi();
RawCode target(const RawCode &code, const match_t &match); RawCode target(const match_t &match);
std::vector<RawCode> target_multi(const RawCode &code, const match_t &match); std::vector<RawCode> target_multi(const match_t &match);
/// static BFS search functions /// static BFS search functions
static std::vector<RawCode> resolve(const RawCode &start); static std::vector<RawCode> resolve(const RawCode &start);
@ -43,6 +45,7 @@ private:
fast_cal_t *last; fast_cal_t *last;
}; };
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;

73
src/main.cc

@ -17,55 +17,50 @@ int main() {
BasicRanges::build(); BasicRanges::build();
// std::vector<RawCode> test_cases; std::vector<RawCode> test_cases;
// { {
// AllCases::build(); AllCases::build();
// std::vector<uint64_t> all_cases; std::vector<uint64_t> all_cases;
// for (uint64_t head = 0; head < 16; ++head) { for (uint64_t head = 0; head < 16; ++head) {
// for (const auto &range : AllCases::fetch()[head]) { for (const auto &range : AllCases::fetch()[head]) {
// all_cases.emplace_back(head << 32 | range); all_cases.emplace_back(head << 32 | range);
// } }
// } }
// for (uint32_t i = 0; i < 1000; ++i) { for (uint32_t i = 0; i < 1000; ++i) {
// test_cases.emplace_back( test_cases.emplace_back(
// RawCode::from_common_code(all_cases.at(i * 29334)) RawCode::from_common_code(all_cases.at(i * 29334))
// ); );
// } }
// } }
// std::cout << "test size -> " << test_cases.size() << std::endl; std::cout << "test size -> " << test_cases.size() << std::endl;
// std::cout << "wait 3s" << std::endl; // std::cout << "wait 3s" << std::endl;
// sleep(3); // sleep(3);
// std::cout << "start benchmark" << std::endl; std::cout << "start benchmark" << std::endl;
auto start_time = clock(); auto start_time = clock();
// AllCases::build(); // AllCases::build();
// { {
// auto fc = FastCal(); auto fc = FastCal(RawCode::unsafe_create(0));
// for (uint32_t i = 0; i < test_cases.size(); ++i) { for (auto code : test_cases) {
// fc.solve(test_cases[i]); fc.set_root(code);
// if (i % 1000 == 0) { fc.solve();
// std::cout << (i * 100 / test_cases.size()) << "%" << std::endl; }
// } }
// }
// for (auto code : test_cases) {
// fc.solve(code);
// }
// }
auto a = Analyse(); // auto a = Analyse();
// a.build((uint64_t)RawCode::from_common_code("1a9bf0c")); // a.build((uint64_t)RawCode::from_common_code("1a9bf0c"));
auto ret = a.build_until((uint64_t)RawCode::from_common_code("1a9bf0c"), [](uint64_t code) { // auto ret = a.build_until((uint64_t)RawCode::from_common_code("1a9bf0c"), [](uint64_t code) {
return ((code >> (3 * 0xD)) & 0b111) == B_2x2; // return ((code >> (3 * 0xD)) & 0b111) == B_2x2;
}); // });
for (const auto &r : ret) { // for (const auto &r : ret) {
std::cout << RawCode(r) << std::endl; // std::cout << RawCode(r) << std::endl;
} // }
// auto raw_code = CommonCode("A5D3AF0").to_raw_code().unwrap(); // 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::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) * 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(); // pause();

Loading…
Cancel
Save