diff --git a/src/core/benchmark/fast_cal.cc b/src/core/benchmark/fast_cal.cc index 52109ce..bdaf120 100644 --- a/src/core/benchmark/fast_cal.cc +++ b/src/core/benchmark/fast_cal.cc @@ -11,9 +11,9 @@ static void FastCalBenchmark(benchmark::State &state) { auto code = CommonCode::unsafe_create(0x1A9BF0C00).to_raw_code(); for (auto _ : state) { - // auto fc = FastCal(code); - // benchmark::DoNotOptimize(fc.solve()); - benchmark::DoNotOptimize(FastCal_demo(code)); + auto fc = FastCal(code); + benchmark::DoNotOptimize(fc.demo()); +// benchmark::DoNotOptimize(FastCal_demo(code)); } } diff --git a/src/core/fast_cal/fast_cal.h b/src/core/fast_cal/fast_cal.h index 9111d0d..59aee58 100644 --- a/src/core/fast_cal/fast_cal.h +++ b/src/core/fast_cal/fast_cal.h @@ -44,6 +44,8 @@ public: RawCode target(const match_t &match); std::vector target_multi(const match_t &match); + RawCode demo(); + /// static BFS search functions static std::vector resolve(const RawCode &start); static std::vector> to_furthest(const RawCode &start); diff --git a/src/core/fast_cal/internal/fast_cal.cc b/src/core/fast_cal/internal/fast_cal.cc index 85479e2..cdb9791 100644 --- a/src/core/fast_cal/internal/fast_cal.cc +++ b/src/core/fast_cal/internal/fast_cal.cc @@ -1,9 +1,13 @@ #include +#include + #include "utils/common.h" #include "fast_cal/fast_cal.h" #include "raw_code/raw_code.h" +#include "group/group.h" + FastCal::FastCal(const RawCode &code) { this->root = (uint64_t)code; } @@ -21,6 +25,51 @@ RawCode FastCal::solve() { return FastCal::target(resolved); } +RawCode FastCal::demo() { + + // max_group_size = 25955 +// auto reserve = klotski::cases::GroupUnion::from_raw_code(RawCode::unsafe_create(root)).max_group_size(); + + cases.reserve(25955); // FAST !!! (about 5ms) +// cases.reserve(32768); // SLOW !!! (about 50ms) + + // TODO: using prime number! + + std::queue{}.swap(cache); + + cache.emplace(&cases.emplace(root, fast_cal_t { + .code = root, + .mask = 0, + .last = nullptr, // without parent node + }).first->second); + + auto core = MaskMover( + [this](uint64_t code, uint64_t mask) { // lambda as function pointer + + auto current = cases.find(code); + if (current != cases.end()) { // find existed case + current->second.mask |= mask; // update mask info + return; + } + cache.emplace(&cases.emplace(code, fast_cal_t { // record new case + .code = code, + .mask = mask, + .last = cache.front(), // link parent case + }).first->second); + + } + ); + + while (!cache.empty()) { + if (((cache.front()->code >> (3 * 0xD)) & 0b111) == BLOCK_2x2) { + return RawCode::unsafe_create(cache.front()->code); // match target + } + core.next_cases(cache.front()->code, cache.front()->mask); + cache.pop(); + } + return FC_NOT_FOUND; // target not found +} + std::vector FastCal::solve_multi() { return FastCal::target_multi(resolved); }