diff --git a/src/analyse/CMakeLists.txt b/src/analyse/CMakeLists.txt index bc7a1e9..3dadefd 100644 --- a/src/analyse/CMakeLists.txt +++ b/src/analyse/CMakeLists.txt @@ -1,4 +1,4 @@ cmake_minimum_required(VERSION 3.0) -add_library(analyse analyse.cc) +add_library(analyse analyse.cc backtrack.cc) target_link_libraries(analyse core) diff --git a/src/analyse/analyse.h b/src/analyse/analyse.h index 883e1c0..784ce44 100644 --- a/src/analyse/analyse.h +++ b/src/analyse/analyse.h @@ -8,6 +8,7 @@ #include "core.h" #include "raw_code.h" +// TODO: try double or 4-times size const uint32_t ANY_MAP_RESERVE = 65536; class Analyse { @@ -42,6 +43,20 @@ private: void new_case(uint64_t code, uint64_t mask); +public: + struct backtrack_t { + uint64_t code; + uint32_t layer_num; + std::list last; + std::list next; + +// bool operator==(const backtrack_t &b) const { +// return b.code == code; +// } + }; + + void backtrack_demo(uint64_t code); + /// backtrack definitions // struct backtrack_t { diff --git a/src/analyse/backtrack.cc b/src/analyse/backtrack.cc index 1fa28ae..cadaae8 100644 --- a/src/analyse/backtrack.cc +++ b/src/analyse/backtrack.cc @@ -1,183 +1,80 @@ +#include "analyse.h" -void dump_python_case(uint64_t raw_code) { - std::string result; - for (int addr = 0; raw_code; ++addr, raw_code >>= 3) { - uint32_t x = addr % 4; - uint32_t y = (addr - x) / 4; - - char block[11]; // eg: `[0,0,1,1]` - - switch (raw_code & 0b111) { - case B_1x1: - sprintf(block, "[%d,%d,1,1],", x, y); - result += block; - break; - case B_1x2: - sprintf(block, "[%d,%d,1,2],", x, y); - result += block; - break; - case B_2x1: - sprintf(block, "[%d,%d,2,1],", x, y); - result += block; - break; - case B_2x2: - sprintf(block, "[%d,%d,2,2],", x, y); - result += block; - break; - default: - continue; - } - } - result[result.length() - 1] = '\0'; // remove last `,` - std::cout << '[' << result.c_str() << ']'; -} - -void Analyse::backtrack(const std::vector &raw_code_list) { - - // backtrack start at code -// std::cout << "start backtrack" << std::endl; - - std::queue track_cache; +#include - std::vector > layer_data; +#include +#include - std::unordered_map track_data; - - // TODO: confirm that code exist - - /// layer init -// auto max_step = cases[code].step; // TODO: update max step cal -// auto max_step = 81; - - uint32_t max_step = 0; - for (const auto &code : raw_code_list) { - // TODO: check whether cases include code - if (cases[code].step > max_step) { - max_step = cases[code].step; - } - } +// TODO: using const RawCode& instead of uint64_t - layer_data.resize(max_step + 1); - - /// init track begin cases -// { -// auto layer_num = cases[code].step; -// -// track_cache.emplace(&cases[code]); -// -// auto ptr = track_data.emplace(code, backtrack_t { -// .code = code, -// .layer_num = layer_num, -// .layer_index = (uint32_t)layer_data[layer_num].size(), -// }); -// -// layer_data[layer_num].emplace_back(&ptr.first->second); +struct backtrack_hash { +// template +// std::size_t operator()(const std::pair &v) const { +// return std::hash()(v.size()); // } - for (auto code : raw_code_list) { + std::size_t operator()(const Analyse::backtrack_t &b) const { + std::cout << "hash -> " << b.code << std::endl; - auto layer_num = cases[code].step; + auto hash_ret = std::hash()(b.code); - track_cache.emplace(&cases[code]); + std::cout << "hash ret -> " << hash_ret << std::endl; - auto ptr = track_data.emplace(code, backtrack_t { - .code = code, - .layer_num = layer_num, - .layer_index = (uint32_t)layer_data[layer_num].size(), - }); - - layer_data[layer_num].emplace_back(&ptr.first->second); + return b.code; } -// for (const auto &t : track_data) { -// std::cout << RawCode(t.second.code).dump_case() << std::endl; -// std::cout << t.second.layer_num << " " << t.second.layer_index << std::endl; -// } +}; - while (!track_cache.front()->src.empty()) { +void Analyse::backtrack_demo(uint64_t code) { - auto current = track_cache.front(); +// std::cout << RawCode(code) << std::endl; - for (auto src : current->src) { + // TODO: confirm code exist + std::cout << cases[code].step << std::endl; - auto find_ret = track_data.find(src->code); - if (find_ret != track_data.end()) { // already exist + std::string str("demo"); + std::hash str_hash; + std::cout << "hash str -> " << str_hash(str) << std::endl; - find_ret->second.next.emplace_back( - &track_data[current->code] - ); + int i = 123; + std::hash int_hash; + std::cout << "hash int -> " << int_hash(i) << std::endl; - } else { // insert new case +// std::vector> dat; - track_cache.emplace(src); + auto b_hash = [](const backtrack_t &b) { + std::cout << "get hash: " << b.code << std::endl; + return (std::size_t)666; + }; - auto ptr = track_data.emplace(src->code, backtrack_t { - .code = src->code, - .layer_num = src->step, - .layer_index = (uint32_t)layer_data[src->step].size(), - .next = std::list{&track_data[current->code]}, - }); + auto b_eq = [](const backtrack_t &b1, const backtrack_t &b2) { + std::cout << "get eq: " << b1.code << " ? " << b2.code << std::endl; + return b1.code == b2.code; + }; - layer_data[src->step].emplace_back(&ptr.first->second); + std::unordered_set test(10, b_hash, b_eq); - } + test.emplace(backtrack_t { + .code = 123, + .layer_num = 0, + .last = std::list{}, + .next = std::list{}, + }); - } - track_cache.pop(); + test.emplace(backtrack_t { + .code = 233, + .layer_num = 1, + .last = std::list{}, + .next = std::list{}, + }); - } - - backtrack_t *root = &track_data[track_cache.front()->code]; - -// std::cout << "Size = " << track_data.size() << std::endl; -// std::cout << "Root" << std::endl; -// std::cout << RawCode(root->code).dump_case() << std::endl; - -// for (auto layer : layer_data) { -// std::cout << "-----------------------" << std::endl; -// std::cout << "layer size = " << layer.size() << std::endl; -// -// for (auto element : layer) { -// std::cout << "(" << element->layer_num << ", " << element->layer_index << ") -> "; -// for (auto next : element->next) { -// std::cout << "(" << next->layer_num << ", " << next->layer_index << ") "; -// } -// std::cout << std::endl; -// -// std::cout << RawCode(element->code).dump_case() << std::endl; -// } -// } - - - printf("layer:\n"); - for (uint32_t num = 0; num < layer_data.size(); ++num) { - auto layer = &layer_data[num]; - printf("- ["); - for (auto element : *layer) { -// printf(&",\"%015lX\""[element == (*layer)[0]], element->code); - printf("%s", &","[element == (*layer)[0]]); - dump_python_case(element->code); - } - printf("] # layer %d\n", num); - } - printf("\n"); - - printf("next:\n"); - for (uint32_t num = 0; num + 1 < layer_data.size(); ++num) { - auto layer = &layer_data[num]; - printf("- "); - for (uint32_t index = 0; index < layer->size(); ++index) { - auto element = &(*layer)[index]; - printf("%s", &" - ["[!index * 2]); - bool first_flag = true; - for (auto next : (*element)->next) { - printf(&",%d"[first_flag], next->layer_index); - if (first_flag) { first_flag = false; } - } - printf("] # (%d, %d) -> %d\n", num, index, num + 1); - } - } + test.emplace(backtrack_t { + .code = 343, + .layer_num = 2, + .last = std::list{}, + .next = std::list{}, + }); diff --git a/src/analyse/backtrack_legacy.cc b/src/analyse/backtrack_legacy.cc new file mode 100644 index 0000000..1fa28ae --- /dev/null +++ b/src/analyse/backtrack_legacy.cc @@ -0,0 +1,184 @@ + +void dump_python_case(uint64_t raw_code) { + std::string result; + for (int addr = 0; raw_code; ++addr, raw_code >>= 3) { + uint32_t x = addr % 4; + uint32_t y = (addr - x) / 4; + + char block[11]; // eg: `[0,0,1,1]` + + switch (raw_code & 0b111) { + case B_1x1: + sprintf(block, "[%d,%d,1,1],", x, y); + result += block; + break; + case B_1x2: + sprintf(block, "[%d,%d,1,2],", x, y); + result += block; + break; + case B_2x1: + sprintf(block, "[%d,%d,2,1],", x, y); + result += block; + break; + case B_2x2: + sprintf(block, "[%d,%d,2,2],", x, y); + result += block; + break; + default: + continue; + } + } + result[result.length() - 1] = '\0'; // remove last `,` + std::cout << '[' << result.c_str() << ']'; +} + +void Analyse::backtrack(const std::vector &raw_code_list) { + + // backtrack start at code +// std::cout << "start backtrack" << std::endl; + + std::queue track_cache; + + std::vector > layer_data; + + std::unordered_map track_data; + + // TODO: confirm that code exist + + /// layer init +// auto max_step = cases[code].step; // TODO: update max step cal +// auto max_step = 81; + + uint32_t max_step = 0; + for (const auto &code : raw_code_list) { + // TODO: check whether cases include code + if (cases[code].step > max_step) { + max_step = cases[code].step; + } + } + + layer_data.resize(max_step + 1); + + /// init track begin cases +// { +// auto layer_num = cases[code].step; +// +// track_cache.emplace(&cases[code]); +// +// auto ptr = track_data.emplace(code, backtrack_t { +// .code = code, +// .layer_num = layer_num, +// .layer_index = (uint32_t)layer_data[layer_num].size(), +// }); +// +// layer_data[layer_num].emplace_back(&ptr.first->second); +// } + + for (auto code : raw_code_list) { + + auto layer_num = cases[code].step; + + track_cache.emplace(&cases[code]); + + auto ptr = track_data.emplace(code, backtrack_t { + .code = code, + .layer_num = layer_num, + .layer_index = (uint32_t)layer_data[layer_num].size(), + }); + + layer_data[layer_num].emplace_back(&ptr.first->second); + } + +// for (const auto &t : track_data) { +// std::cout << RawCode(t.second.code).dump_case() << std::endl; +// std::cout << t.second.layer_num << " " << t.second.layer_index << std::endl; +// } + + while (!track_cache.front()->src.empty()) { + + auto current = track_cache.front(); + + for (auto src : current->src) { + + auto find_ret = track_data.find(src->code); + + if (find_ret != track_data.end()) { // already exist + + find_ret->second.next.emplace_back( + &track_data[current->code] + ); + + } else { // insert new case + + track_cache.emplace(src); + + auto ptr = track_data.emplace(src->code, backtrack_t { + .code = src->code, + .layer_num = src->step, + .layer_index = (uint32_t)layer_data[src->step].size(), + .next = std::list{&track_data[current->code]}, + }); + + layer_data[src->step].emplace_back(&ptr.first->second); + + } + + } + track_cache.pop(); + + } + + backtrack_t *root = &track_data[track_cache.front()->code]; + +// std::cout << "Size = " << track_data.size() << std::endl; +// std::cout << "Root" << std::endl; +// std::cout << RawCode(root->code).dump_case() << std::endl; + +// for (auto layer : layer_data) { +// std::cout << "-----------------------" << std::endl; +// std::cout << "layer size = " << layer.size() << std::endl; +// +// for (auto element : layer) { +// std::cout << "(" << element->layer_num << ", " << element->layer_index << ") -> "; +// for (auto next : element->next) { +// std::cout << "(" << next->layer_num << ", " << next->layer_index << ") "; +// } +// std::cout << std::endl; +// +// std::cout << RawCode(element->code).dump_case() << std::endl; +// } +// } + + + printf("layer:\n"); + for (uint32_t num = 0; num < layer_data.size(); ++num) { + auto layer = &layer_data[num]; + printf("- ["); + for (auto element : *layer) { +// printf(&",\"%015lX\""[element == (*layer)[0]], element->code); + printf("%s", &","[element == (*layer)[0]]); + dump_python_case(element->code); + } + printf("] # layer %d\n", num); + } + printf("\n"); + + printf("next:\n"); + for (uint32_t num = 0; num + 1 < layer_data.size(); ++num) { + auto layer = &layer_data[num]; + printf("- "); + for (uint32_t index = 0; index < layer->size(); ++index) { + auto element = &(*layer)[index]; + printf("%s", &" - ["[!index * 2]); + bool first_flag = true; + for (auto next : (*element)->next) { + printf(&",%d"[first_flag], next->layer_index); + if (first_flag) { first_flag = false; } + } + printf("] # (%d, %d) -> %d\n", num, index, num + 1); + } + } + + + +} diff --git a/src/main.cc b/src/main.cc index 24f97ad..b42c236 100644 --- a/src/main.cc +++ b/src/main.cc @@ -41,7 +41,7 @@ int main() { // sleep(3); // std::cout << "start benchmark" << std::endl; -// auto start_time = clock(); + auto start_time = clock(); // { @@ -54,18 +54,21 @@ int main() { auto a = Analyse(RawCode::from_common_code("1a9bf0c")); - a.build(); -// auto ret = a.build_until([](uint64_t code) { -// return ((code >> (3 * 0xD)) & 0b111) == B_2x2; -// }); +// a.build(); + auto ret = a.build_until([](uint64_t code) { + return ((code >> (3 * 0xD)) & 0b111) == B_2x2; + }); // for (const auto &r : ret) { // std::cout << r << std::endl; // } - auto start_time = clock(); + a.backtrack_demo(0x7F87E0E5BFFF492); +// a.backtrack_demo(0x1FB1E36F9FFF492); + +// auto start_time = clock(); - std::cout << a.layer_export(81).size() << std::endl; - std::cout << a.layer_export()[81].size() << std::endl; +// std::cout << a.layer_export(81).size() << std::endl; +// std::cout << a.layer_export()[81].size() << std::endl; // auto raw_code = CommonCode("A5D3AF0").to_raw_code().unwrap(); @@ -108,7 +111,7 @@ int main() { // 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::cout << "complete benchmark" << std::endl; +// std::cout << "complete benchmark" << std::endl; // pause();