|
|
@ -1,11 +1,6 @@ |
|
|
|
#include "fast_cal/fast_cal.h" |
|
|
|
|
|
|
|
#include <iostream> |
|
|
|
|
|
|
|
#include <parallel_hashmap/phmap.h> |
|
|
|
|
|
|
|
#include "mover/mover.h" |
|
|
|
#include "group/group.h" |
|
|
|
#include "fast_cal/fast_cal.h" |
|
|
|
|
|
|
|
using klotski::codec::RawCode; |
|
|
|
using klotski::codec::CommonCode; |
|
|
@ -16,8 +11,8 @@ using klotski::cases::GroupUnion; |
|
|
|
|
|
|
|
using klotski::fast_cal::FastCalPro; |
|
|
|
|
|
|
|
static KLSK_INLINE bool is_solved(uint64_t raw_code) { |
|
|
|
return ((raw_code >> 39) & 0b111) == 0b100; |
|
|
|
static KLSK_INLINE bool is_solved(RawCode raw_code) { |
|
|
|
return ((raw_code.unwrap() >> 39) & 0b111) == 0b100; |
|
|
|
} |
|
|
|
|
|
|
|
std::optional<RawCode> FastCalPro::solve() { |
|
|
@ -26,9 +21,9 @@ std::optional<RawCode> FastCalPro::solve() { |
|
|
|
// }
|
|
|
|
|
|
|
|
uint64_t solution = 0; |
|
|
|
auto mover = MaskMover([this, &solution](uint64_t code, uint64_t mask) { |
|
|
|
auto mover = MaskMover([this, &solution](RawCode code, uint64_t mask) { |
|
|
|
if (try_emplace(code, mask) && is_solved(code)) { |
|
|
|
solution = code; |
|
|
|
solution = code.unwrap(); |
|
|
|
} |
|
|
|
}); |
|
|
|
while (!codes_.is_ending()) { |
|
|
@ -44,9 +39,9 @@ std::optional<RawCode> FastCalPro::search(std::function<bool(RawCode)> &&match) |
|
|
|
// TODO: check root case
|
|
|
|
|
|
|
|
uint64_t target = 0; |
|
|
|
auto mover = MaskMover([this, &target, match = std::move(match)](uint64_t code, uint64_t mask) { |
|
|
|
if (try_emplace(code, mask) && match(RawCode::unsafe_create(code))) { |
|
|
|
target = code; |
|
|
|
auto mover = MaskMover([this, &target, match = std::move(match)](RawCode code, uint64_t mask) { |
|
|
|
if (try_emplace(code, mask) && match(code)) { |
|
|
|
target = code.unwrap(); |
|
|
|
} |
|
|
|
}); |
|
|
|
while (!codes_.is_ending()) { |
|
|
@ -64,17 +59,16 @@ std::vector<RawCode> FastCalPro::solve_multi() { |
|
|
|
bool stop_flag = false; |
|
|
|
std::vector<RawCode> results {}; |
|
|
|
|
|
|
|
auto mover = MaskMover([this, &stop_flag, &results](uint64_t code, uint64_t mask) { |
|
|
|
auto mover = MaskMover([this, &stop_flag, &results](RawCode code, uint64_t mask) { |
|
|
|
if (try_emplace(code, mask) && is_solved(code)) { |
|
|
|
stop_flag = true; |
|
|
|
results.emplace_back(RawCode::unsafe_create(code)); |
|
|
|
results.emplace_back(code); |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
while (!codes_.is_ending()) { |
|
|
|
spawn_next(mover); |
|
|
|
if (codes_.is_new_layer() && stop_flag) { |
|
|
|
// TODO: fix when solutions at last layer
|
|
|
|
if (stop_flag && (codes_.is_new_layer() || codes_.is_ending())) { |
|
|
|
return results; |
|
|
|
} |
|
|
|
|
|
|
@ -82,26 +76,30 @@ std::vector<RawCode> FastCalPro::solve_multi() { |
|
|
|
return {}; |
|
|
|
} |
|
|
|
|
|
|
|
std::vector<RawCode> FastCalPro::furthest() { |
|
|
|
auto mover = MaskMover([this](uint64_t code, uint64_t mask) { |
|
|
|
void FastCalPro::build() { |
|
|
|
auto mover = MaskMover([this](RawCode code, uint64_t mask) { |
|
|
|
try_emplace(code, mask); |
|
|
|
}); |
|
|
|
while (true) { |
|
|
|
while (!codes_.is_ending()) { |
|
|
|
spawn_next(mover); |
|
|
|
if (codes_.is_ending()) { |
|
|
|
return codes_.last_layer(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
std::vector<RawCode> FastCalPro::furthest() { |
|
|
|
if (!codes_.is_ending()) { |
|
|
|
build(); |
|
|
|
} |
|
|
|
return codes_.last_layer(); |
|
|
|
} |
|
|
|
|
|
|
|
std::vector<RawCode> FastCalPro::backtrack(RawCode code) const { |
|
|
|
if (const auto match = cases_.find(code.unwrap()); match == cases_.end()) { |
|
|
|
if (const auto match = cases_.find(code); match == cases_.end()) { |
|
|
|
return {}; // case not found
|
|
|
|
} |
|
|
|
std::vector<RawCode> path; |
|
|
|
while (code != 0) { |
|
|
|
path.emplace_back(code); |
|
|
|
code = RawCode::unsafe_create(cases_.find(code.unwrap())->second.back); |
|
|
|
code = cases_.find(code)->second.back; |
|
|
|
} |
|
|
|
std::reverse(path.begin(), path.end()); |
|
|
|
return path; |