From 37a620c5039cf0750b67829c10c5f54df48aea86 Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Thu, 19 Jan 2023 18:33:09 +0800 Subject: [PATCH] feat: enable Analyse module --- src/CMakeLists.txt | 4 +- src/analyse/analyse.cc | 258 ++++----------------------------------- src/analyse/analyse.h | 32 +++-- src/analyse/backtrack.cc | 184 ++++++++++++++++++++++++++++ src/fast_cal/fast_cal.h | 2 +- src/main.cc | 68 ++++++----- 6 files changed, 265 insertions(+), 283 deletions(-) create mode 100644 src/analyse/backtrack.cc diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d8772ac..a1b014f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -23,7 +23,7 @@ add_subdirectory(short_code) add_subdirectory(common_code) add_subdirectory(core) -#add_subdirectory(analyse) +add_subdirectory(analyse) add_subdirectory(fast_cal) ################################################ @@ -40,7 +40,7 @@ target_link_libraries(klotski short_code) target_link_libraries(klotski common_code) target_link_libraries(klotski core) -#target_link_libraries(klotski analyse) +target_link_libraries(klotski analyse) target_link_libraries(klotski fast_cal) target_link_libraries(klotski pthread) diff --git a/src/analyse/analyse.cc b/src/analyse/analyse.cc index 269eede..9fd6d49 100644 --- a/src/analyse/analyse.cc +++ b/src/analyse/analyse.cc @@ -7,7 +7,7 @@ #include "raw_code.h" #include "common.h" -Core Analyse::new_core() { +Core Analyse::init() { return Core( [this](auto &&code, auto &&mask) { // lambda as function pointer new_case(std::forward(code), std::forward(mask)); @@ -15,260 +15,54 @@ Core Analyse::new_core() { ); } -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]); +void Analyse::build(uint64_t 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(); + auto core = init(); - } - - 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); - } - } - - - -} - -void Analyse::start_analyse(uint64_t code) { - - auto core = new_core(); + cases.clear(); + cases.reserve(65536); - cases.empty(); - cache.empty(); + std::queue{}.swap(cache); - cases.reserve(65536); cache.emplace(&cases.emplace(code, analyse_t { .code = code, .mask = 0, .step = 0, -// .highlight = false, -// .src = std::move(std::list{}), + .src = std::list{}, +// .src = std::vector{}, +// .src = std::set{}, +// .src = std::unordered_set{}, }).first->second); while (!cache.empty()) { - - core.next_step(cache.front()->code, cache.front()->mask); + core.next_cases(cache.front()->code, cache.front()->mask); cache.pop(); } -// std::cout << "size: " << cases.size() << std::endl; + std::cout << "size: " << cases.size() << std::endl; } void Analyse::new_case(uint64_t code, uint64_t mask) { - - -// auto temp = cases.emplace(code, analyse_t { -// .code = code, -// .mask = mask, -// .step = cache.front()->step + 1, -// .src = std::move(std::list{cache.front()}) -// }); -// -// if (temp.second) { -// cache.emplace(&temp.first->second); -// } else { -// temp.first->second.mask |= mask; -// -// if (temp.first->second.step != cache.front()->step) { -// temp.first->second.src.push_back(cache.front()); -// } -// -// } - auto current = cases.find(code); - if (current != cases.end()) { // find existed case - - if (current->second.step == cache.front()->step + 1) { - + if (current != cases.end()) { // new case already exist + if (current->second.step == cache.front()->step + 1) { // new case at next layer current->second.mask |= mask; // update mask info - - if (current->second.step != cache.front()->step) { - current->second.src.push_back(cache.front()); - } - + current->second.src.emplace_back(cache.front()); // link more parent case +// current->second.src.emplace(cache.front()); // link more parent case } - - return; + } else { // new case not exist + cache.emplace(&cases.emplace(code, analyse_t { // record new case + .code = code, + .mask = mask, + .step = cache.front()->step + 1, + .src = std::list{cache.front()}, // link parent case +// .src = std::vector{cache.front()}, // link parent case +// .src = std::set{cache.front()}, // link parent case +// .src = std::unordered_set{cache.front()}, // link parent case + }).first->second); } - - cache.emplace(&cases.emplace(code, analyse_t { - .code = code, - .mask = mask, - .step = cache.front()->step + 1, -// .highlight = false, - .src = std::move(std::list{cache.front()}), - }).first->second); - } diff --git a/src/analyse/analyse.h b/src/analyse/analyse.h index c39e301..c993765 100644 --- a/src/analyse/analyse.h +++ b/src/analyse/analyse.h @@ -4,45 +4,43 @@ #include #include -//#include #include -//#include +#include +#include class Analyse { public: struct analyse_t { uint64_t code; uint64_t mask; - uint32_t step; -// bool highlight; - -// std::vector src; std::list src; +// std::vector src; // std::set src; // std::unordered_set src; }; - struct backtrack_t { - uint64_t code; - - uint32_t layer_num; - uint32_t layer_index; - - std::list next; - }; +// struct backtrack_t { +// uint64_t code; +// uint32_t layer_num; +// uint32_t layer_index; +// std::list next; +// }; std::queue cache; std::unordered_map cases; - inline Core new_core(); +// inline Core new_core(); // TODO: backtrack for multi-codes // void backtrack(uint64_t code); - void backtrack(const std::vector &raw_code_list); +// void backtrack(const std::vector &raw_code_list); + + void build(uint64_t code); - void start_analyse(uint64_t code); +// inline Core init(uint64_t code); + inline Core init(); void new_case(uint64_t code, uint64_t mask); diff --git a/src/analyse/backtrack.cc b/src/analyse/backtrack.cc new file mode 100644 index 0000000..1fa28ae --- /dev/null +++ b/src/analyse/backtrack.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/fast_cal/fast_cal.h b/src/fast_cal/fast_cal.h index a927aff..5b8ff1b 100644 --- a/src/fast_cal/fast_cal.h +++ b/src/fast_cal/fast_cal.h @@ -44,6 +44,6 @@ private: std::queue cache; std::unordered_map cases; - Core init(uint64_t code); + inline Core init(uint64_t code); void new_case(uint64_t code, uint64_t mask); }; diff --git a/src/main.cc b/src/main.cc index c8ca9fe..4552d89 100644 --- a/src/main.cc +++ b/src/main.cc @@ -15,46 +15,52 @@ 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 < 10000; ++i) { - test_cases.emplace_back( - RawCode::from_common_code(all_cases.at(i * 2933)) - ); - } - } - std::cout << "test size -> " << test_cases.size() << std::endl; + 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::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; - } - } - } +// { +// 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 a = Analyse(); + a.build((uint64_t)RawCode::from_common_code("1a9bf0c")); + // auto raw_code = CommonCode("A5D3AF0").to_raw_code().unwrap(); // auto a = Analyse(); @@ -92,11 +98,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();