diff --git a/src/analyse/analyse.cc b/src/analyse/analyse.cc index 9fd6d49..96629bd 100644 --- a/src/analyse/analyse.cc +++ b/src/analyse/analyse.cc @@ -26,43 +26,84 @@ void Analyse::build(uint64_t code) { std::queue{}.swap(cache); + cache.emplace(&cases.emplace(code, analyse_t { + .code = code, + .mask = 0, + .step = 0, + .src = std::list{}, + }).first->second); + + while (!cache.empty()) { + core.next_cases(cache.front()->code, cache.front()->mask); + cache.pop(); + } + + std::cout << "size: " << cases.size() << std::endl; + +} + +std::vector Analyse::build_until(uint64_t code, const Analyse::match_t &match) { + + auto core = init(); + + cases.clear(); + cases.reserve(65536); + + std::queue{}.swap(cache); cache.emplace(&cases.emplace(code, analyse_t { .code = code, .mask = 0, .step = 0, - .src = std::list{}, -// .src = std::vector{}, -// .src = std::set{}, -// .src = std::unordered_set{}, + .src = std::list{}, }).first->second); + + auto layer_end = cache.back(); + std::vector matched; // matched list + + 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); + + if (cache.front() == layer_end) { // reach layer ending + if (!matched.empty()) { + + std::cout << "size: " << cases.size() << std::endl; + + return matched; // stop at first matched layer + } + layer_end = cache.back(); // reset layer ending + } + cache.pop(); } std::cout << "size: " << cases.size() << std::endl; + return std::vector{}; // no target found + } + void Analyse::new_case(uint64_t code, uint64_t mask) { auto current = cases.find(code); 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 current->second.src.emplace_back(cache.front()); // link more parent case -// current->second.src.emplace(cache.front()); // link more parent case } } 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 + .src = std::list{cache.front()}, // link parent case }).first->second); } } + diff --git a/src/analyse/analyse.h b/src/analyse/analyse.h index c993765..93e8400 100644 --- a/src/analyse/analyse.h +++ b/src/analyse/analyse.h @@ -37,8 +37,12 @@ public: // void backtrack(uint64_t code); // void backtrack(const std::vector &raw_code_list); + typedef std::function match_t; + void build(uint64_t code); + std::vector build_until(uint64_t code, const match_t &match); + // inline Core init(uint64_t code); inline Core init(); diff --git a/src/fast_cal/fast_cal.h b/src/fast_cal/fast_cal.h index 5b8ff1b..1835aed 100644 --- a/src/fast_cal/fast_cal.h +++ b/src/fast_cal/fast_cal.h @@ -19,6 +19,8 @@ public: 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); diff --git a/src/main.cc b/src/main.cc index 4552d89..71aa55b 100644 --- a/src/main.cc +++ b/src/main.cc @@ -59,7 +59,13 @@ int main() { 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) { + 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();