Browse Source

update: interfaces of fast cal

master
Dnomd343 3 weeks ago
parent
commit
a9f53602e4
  1. 34
      src/core/fast_cal/fast_cal.h
  2. 114
      src/core/fast_cal/internal/demo.cc
  3. 21
      src/core/fast_cal/internal/fast_cal.inl

34
src/core/fast_cal/fast_cal.h

@ -109,17 +109,39 @@ private:
namespace klotski::fast_cal { namespace klotski::fast_cal {
class FCDemo { class FastCalPro {
public: public:
explicit FCDemo(RawCode raw_code); FastCalPro() = delete;
std::optional<RawCode> DoCal(); explicit FastCalPro(RawCode raw_code);
std::vector<RawCode> DoCalMulti(); // ------------------------------------------------------------------------------------- //
std::vector<RawCode> DoCalFurthest(); /// Calculate the case with minimum steps.
std::optional<RawCode> solve();
/// Calculate the cases with maximum steps.
std::vector<RawCode> furthest();
/// Calculate all of the minimum-step cases.
std::vector<RawCode> solve_multi();
/// Calculate the first case that meets the requirement.
std::optional<RawCode> achieve(std::function<bool(RawCode)> &&match);
// ------------------------------------------------------------------------------------- //
private: private:
// ------------------------------------------------------------------------------------- //
/// Search next step cases and pop current.
KLSK_INLINE void spawn_next(MaskMover &mover);
/// Try to emplace the searched info into the cache.
KLSK_INLINE bool try_emplace(uint64_t code, uint64_t mask);
// ------------------------------------------------------------------------------------- //
struct data_t { struct data_t {
uint64_t mask; uint64_t mask;
uint64_t back; uint64_t back;
@ -127,6 +149,8 @@ private:
LayerQueue<uint64_t> codes_; LayerQueue<uint64_t> codes_;
phmap::flat_hash_map<uint64_t, data_t> cases_; phmap::flat_hash_map<uint64_t, data_t> cases_;
// ------------------------------------------------------------------------------------- //
}; };
} // namespace klotski::fast_cal } // namespace klotski::fast_cal

114
src/core/fast_cal/internal/demo.cc

@ -16,64 +16,63 @@ using klotski::cases::RangesUnion;
using klotski::mover::MaskMover; using klotski::mover::MaskMover;
using klotski::cases::GroupUnion; using klotski::cases::GroupUnion;
using klotski::fast_cal::FCDemo; using klotski::fast_cal::FastCalPro;
std::optional<RawCode> FCDemo::DoCal() {
uint64_t result = 0;
auto core = MaskMover([this, &result](uint64_t code, uint64_t mask) {
if (const auto match = cases_.find(code); match != cases_.end()) {
match->second.mask |= mask; // update mask
return;
}
cases_.emplace(code, data_t {
.mask = mask,
.back = codes_.current(),
});
codes_.emplace(code);
if (((code >> 39) & 0b111) == 0b100) { static KLSK_INLINE bool is_solved(uint64_t raw_code) {
result = code; return ((raw_code >> 39) & 0b111) == 0b100;
} }
});
while (!codes_.is_ending()) { std::optional<RawCode> FastCalPro::solve() {
auto curr = codes_.current(); // TODO: check root case
core.next_cases(curr, cases_.find(curr)->second.mask);
codes_.next(); uint64_t solution = 0;
if (result != 0) { auto mover = MaskMover([this, &solution](uint64_t code, uint64_t mask) {
return RawCode::unsafe_create(result); if (try_emplace(code, mask) && is_solved(code)) {
solution = code;
}
});
while (!codes_.is_ending()) {
spawn_next(mover);
if (solution != 0) {
return RawCode::unsafe_create(solution);
} }
} }
return std::nullopt; return std::nullopt;
} }
std::vector<RawCode> FCDemo::DoCalMulti() { std::optional<RawCode> FastCalPro::achieve(std::function<bool(RawCode)> &&match) {
bool stop_flag = false; // TODO: check root case
std::vector<RawCode> results {};
auto core = MaskMover([this, &stop_flag, &results](uint64_t code, uint64_t mask) { uint64_t target = 0;
if (const auto match = cases_.find(code); match != cases_.end()) { auto mover = MaskMover([this, &target, match = std::move(match)](uint64_t code, uint64_t mask) {
match->second.mask |= mask; // update mask if (try_emplace(code, mask) && match(RawCode::unsafe_create(code))) {
return; target = code;
} }
cases_.emplace(code, data_t {
.mask = mask,
.back = codes_.current(),
}); });
codes_.emplace(code); while (!codes_.is_ending()) {
spawn_next(mover);
if (target != 0) {
return RawCode::unsafe_create(target);
}
}
return std::nullopt;
}
std::vector<RawCode> FastCalPro::solve_multi() {
// TODO: check root case
bool stop_flag = false;
std::vector<RawCode> results {};
if (((code >> 39) & 0b111) == 0b100) { auto mover = MaskMover([this, &stop_flag, &results](uint64_t code, uint64_t mask) {
if (try_emplace(code, mask) && is_solved(code)) {
stop_flag = true; stop_flag = true;
results.emplace_back(RawCode::unsafe_create(code)); results.emplace_back(RawCode::unsafe_create(code));
} }
}); });
while (!codes_.is_ending()) { while (!codes_.is_ending()) {
auto curr = codes_.current(); spawn_next(mover);
core.next_cases(curr, cases_.find(curr)->second.mask);
codes_.next();
if (codes_.is_new_layer() && stop_flag) { if (codes_.is_new_layer() && stop_flag) {
// TODO: fix when solutions at last layer // TODO: fix when solutions at last layer
return results; return results;
@ -83,24 +82,12 @@ std::vector<RawCode> FCDemo::DoCalMulti() {
return {}; return {};
} }
std::vector<RawCode> FCDemo::DoCalFurthest() { std::vector<RawCode> FastCalPro::furthest() {
auto core = MaskMover([this](uint64_t code, uint64_t mask) { auto mover = MaskMover([this](uint64_t code, uint64_t mask) {
if (const auto match = cases_.find(code); match != cases_.end()) { try_emplace(code, mask);
match->second.mask |= mask; // update mask
return;
}
cases_.emplace(code, data_t {
.mask = mask,
.back = codes_.current(),
});
codes_.emplace(code);
}); });
while (true) { while (true) {
auto curr = codes_.current(); spawn_next(mover);
core.next_cases(curr, cases_.find(curr)->second.mask);
codes_.next();
if (codes_.is_ending()) { if (codes_.is_ending()) {
return codes_.layer_cases() | std::views::transform([](uint64_t code) { return codes_.layer_cases() | std::views::transform([](uint64_t code) {
return RawCode::unsafe_create(code); return RawCode::unsafe_create(code);
@ -110,21 +97,26 @@ std::vector<RawCode> FCDemo::DoCalFurthest() {
} }
RawCode FastCal_demo(RawCode raw_code) { RawCode FastCal_demo(RawCode raw_code) {
klotski::fast_cal::FCDemo fc {raw_code}; klotski::fast_cal::FastCalPro fc {raw_code};
// return fc.DoCal().value(); return fc.solve().value();
// auto tmp = fc.DoCal(); // auto tmp = fc.solve();
// std::cout << tmp.value().to_common_code() << std::endl; // std::cout << tmp.value().to_common_code() << std::endl;
// auto tmp = fc.DoCalMulti(); // auto tmp = fc.solve_multi();
// for (const auto x : tmp) { // for (const auto x : tmp) {
// std::cout << x.to_common_code() << std::endl; // std::cout << x.to_common_code() << std::endl;
// } // }
auto tmp = fc.DoCalFurthest(); // auto tmp = fc.furthest();
// for (const auto x : tmp) { // for (const auto x : tmp) {
// std::cout << x.to_common_code() << std::endl; // std::cout << x.to_common_code() << std::endl;
// } // }
return RawCode::unsafe_create(0); // auto tmp = fc.achieve([](RawCode r) {
// return r == 0x7F87E0E5BFFF492;
// });
// std::cout << tmp.value().to_common_code() << std::endl;
// return RawCode::unsafe_create(0);
} }

21
src/core/fast_cal/internal/fast_cal.inl

@ -2,11 +2,30 @@
namespace klotski::fast_cal { namespace klotski::fast_cal {
inline FCDemo::FCDemo(RawCode raw_code) : codes_(cases::GroupUnion::from_raw_code(raw_code).max_group_size(), {raw_code.unwrap()}) { inline FastCalPro::FastCalPro(RawCode raw_code) : codes_(cases::GroupUnion::from_raw_code(raw_code).max_group_size(), {raw_code.unwrap()}) {
// auto reserve = cases::GroupUnion::from_raw_code(raw_code).max_group_size(); // auto reserve = cases::GroupUnion::from_raw_code(raw_code).max_group_size();
cases_.reserve(static_cast<size_t>(25955 * 1.56)); cases_.reserve(static_cast<size_t>(25955 * 1.56));
// cases_.reserve(static_cast<size_t>(reserve * 1.56)); // cases_.reserve(static_cast<size_t>(reserve * 1.56));
cases_.emplace(raw_code, data_t {0, 0}); // without mask cases_.emplace(raw_code, data_t {0, 0}); // without mask
} }
inline KLSK_INLINE bool FastCalPro::try_emplace(uint64_t code, uint64_t mask) {
if (const auto match = cases_.find(code); match != cases_.end()) {
match->second.mask |= mask; // update mask
return false;
}
cases_.emplace(code, data_t {
.mask = mask,
.back = codes_.current(),
});
codes_.emplace(code);
return true;
}
inline KLSK_INLINE void FastCalPro::spawn_next(MaskMover &mover) {
auto curr = codes_.current();
mover.next_cases(curr, cases_.find(curr)->second.mask);
codes_.next();
}
} // namespace klotski::fast_cal } // namespace klotski::fast_cal

Loading…
Cancel
Save