华容道高性能计算引擎
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

140 lines
3.9 KiB

#include <queue>
#include <iostream>
#include "absl/container/flat_hash_map.h"
#include "group.h"
#include "common.h"
#include "core.h"
namespace klotski {
using Common::range_reverse;
Group::block_num_t Group::block_num(const RawCode &raw_code) {
block_num_t result;
auto tmp = raw_code.unwrap();
for (int addr = 0; addr < 20; ++addr, tmp >>= 3) {
switch (tmp & 0b111) {
case B_1x1:
++result.n_1x1;
continue;
case B_1x2:
++result.n_1x2;
continue;
case B_2x1:
++result.n_2x1;
continue;
}
}
return result;
}
Group::block_num_t Group::block_num(const CommonCode &common_code) {
block_num_t result;
auto range = range_reverse((uint32_t)common_code.unwrap());
for (; range; range >>= 2) {
switch (range & 0b11) {
case 0b01: /// 1x2 block
++result.n_1x2;
continue;
case 0b10: /// 2x1 block
++result.n_2x1;
continue;
case 0b11: /// 1x1 block
++result.n_1x1;
continue;
}
}
return result;
}
uint32_t Group::demo(const RawCode &seed) {
// struct group_cal_t {
// uint64_t code;
// uint64_t mask;
// };
// std::queue<group_cal_t*> cache;
// std::queue<uint64_t> cache;
// std::queue<std::pair<uint64_t, uint64_t>> cache;
//
// absl::flat_hash_map<uint64_t, group_cal_t> cases;
// absl::flat_hash_map<uint64_t, uint64_t> cases;
// absl::flat_hash_map<uint64_t, std::unique_ptr<group_cal_t>> cases;
std::queue<uint64_t> cache;
std::queue<uint64_t> cache_;
absl::flat_hash_map<uint64_t, uint64_t> cases;
cases.reserve(65535 * 8);
// cache.emplace(&cases.emplace(seed.unwrap(), group_cal_t {
// .code = seed.unwrap(),
// .mask = 0,
// }).first->second);
// cases.emplace(seed.unwrap(), 0);
// cache.emplace(seed.unwrap());
// cache.emplace(seed.unwrap(), 0);
// cases.emplace(seed.unwrap(), std::make_unique<group_cal_t>(group_cal_t {
// .code = seed.unwrap(),
// .mask = 0,
// }));
cases.emplace(seed.unwrap(), 0);
cache.emplace(seed.unwrap());
cache_.emplace(0);
auto core = Core(
[&cases, &cache, &cache_](auto &&code, auto &&mask) {
auto current = cases.find(code);
if (current != cases.end()) { // find existed case
// current->second.mask |= mask; // update mask info
// current->second |= mask;
// current->second->mask |= mask;
current->second |= mask; // update mask info
return;
}
// cache.emplace(&cases.emplace(code, group_cal_t {
// .code = code,
// .mask = mask,
// }).first->second);
// cases.emplace(code, mask);
// cache.emplace(code);
// cache.emplace(code, mask);
// cases.emplace(code, std::make_unique<group_cal_t>(group_cal_t {
// .code = code,
// .mask = mask,
// }));
cases.emplace(code, mask);
cache.emplace(code);
cache_.emplace(mask);
}
);
while (!cache.empty()) {
// core.next_cases(cache.front()->code, cache.front()->mask);
// core.next_cases(cache.front(), cases.find(cache.front())->second);
// core.next_cases(cache.front().first, cache.front().second);
// core.next_cases(cache.front(), cases.find(cache.front())->second->mask);
// core.next_cases(cache.front(), cases.find(cache.front())->second);
core.next_cases(cache.front(), cache_.front());
cache.pop();
cache_.pop();
}
// std::cout << cases.size() << std::endl;
return cases.size();
}
} // namespace klotski