|
@ -1,4 +1,5 @@ |
|
|
#include <queue> |
|
|
#include <queue> |
|
|
|
|
|
#include <vector> |
|
|
#include "core.h" |
|
|
#include "core.h" |
|
|
#include "group.h" |
|
|
#include "group.h" |
|
|
#include "common.h" |
|
|
#include "common.h" |
|
@ -46,51 +47,37 @@ Group::block_num_t Group::block_num(const CommonCode &common_code) { |
|
|
return result; |
|
|
return result; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
uint32_t Group::demo(const RawCode &seed) { |
|
|
std::vector<RawCode> Group::group_cases(const RawCode &seed) { |
|
|
std::queue<uint64_t> cache; |
|
|
std::queue<uint64_t> cache; |
|
|
|
|
|
absl::flat_hash_map<uint64_t, uint64_t> cases; // <code, mask>
|
|
|
// uint32_t index = 0;
|
|
|
cases.reserve(max_group_size(seed)); |
|
|
// std::vector<uint64_t> temp;
|
|
|
|
|
|
// temp.reserve(65535 * 8);
|
|
|
|
|
|
|
|
|
|
|
|
absl::flat_hash_map<uint64_t, uint64_t> cases; |
|
|
|
|
|
|
|
|
|
|
|
cases.reserve(65535 * 8); |
|
|
|
|
|
|
|
|
|
|
|
cases.emplace(seed.unwrap(), 0); // without mask
|
|
|
cases.emplace(seed.unwrap(), 0); // without mask
|
|
|
cache.emplace(seed.unwrap()); |
|
|
cache.emplace(seed.unwrap()); |
|
|
|
|
|
|
|
|
// temp.emplace_back(seed.unwrap());
|
|
|
|
|
|
|
|
|
|
|
|
auto core = Core( |
|
|
auto core = Core( |
|
|
[&cases, &cache](auto &&code, auto &&mask) { |
|
|
[&cache, &cases](auto &&code, auto &&mask) { // callback function
|
|
|
auto current = cases.find(code); |
|
|
auto current = cases.find(code); |
|
|
|
|
|
|
|
|
if (current != cases.end()) { |
|
|
if (current != cases.end()) { |
|
|
current->second |= mask; // update mask info
|
|
|
current->second |= mask; // update mask
|
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
cases.emplace(code, mask); |
|
|
cases.emplace(code, mask); |
|
|
cache.emplace(code); |
|
|
cache.emplace(code); |
|
|
// temp.emplace_back(code);
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
); |
|
|
); |
|
|
|
|
|
while (!cache.empty()) { // until BFS without elements
|
|
|
while (!cache.empty()) { |
|
|
|
|
|
// while (index != temp.size()) {
|
|
|
|
|
|
|
|
|
|
|
|
core.next_cases(cache.front(), cases.find(cache.front())->second); |
|
|
core.next_cases(cache.front(), cases.find(cache.front())->second); |
|
|
// core.next_cases(temp[index], cases.find(temp[index])->second);
|
|
|
cache.pop(); // case dequeue
|
|
|
|
|
|
|
|
|
cache.pop(); |
|
|
|
|
|
// ++index;
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return cases.size(); |
|
|
auto result = std::vector<RawCode>(); |
|
|
|
|
|
result.reserve(cases.size()); |
|
|
|
|
|
for (auto &&raw_code : cases) { // export group cases
|
|
|
|
|
|
result.emplace_back(RawCode::unsafe_create(raw_code.first)); |
|
|
|
|
|
} |
|
|
|
|
|
return result; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace klotski
|
|
|
} // namespace klotski
|
|
|