|
@ -27,81 +27,74 @@ namespace std { |
|
|
}; |
|
|
}; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void Analyse::backtrack_demo(uint64_t code) { |
|
|
void Analyse::backtrack_demo(const std::vector<uint64_t> &codes) { |
|
|
|
|
|
|
|
|
// TODO: confirm code exist
|
|
|
// TODO: confirm code exist
|
|
|
std::cout << cases[code].step << std::endl; |
|
|
// std::cout << cases[code].step << std::endl;
|
|
|
|
|
|
|
|
|
// TODO: only test for now
|
|
|
struct cache_t { |
|
|
// uint32_t layer_size = cases[code].step + 1; // 81 steps -> 0 ~ 81 -> size = 82
|
|
|
analyse_t *a; |
|
|
|
|
|
backtrack_t *b; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
std::queue<cache_t> track_cache; |
|
|
std::vector<std::unordered_map<uint64_t, backtrack_t>> track_data; |
|
|
std::vector<std::unordered_map<uint64_t, backtrack_t>> track_data; |
|
|
|
|
|
|
|
|
/// init process -> insert backtrack begin cases
|
|
|
|
|
|
|
|
|
|
|
|
track_data.resize(82); // TODO: setting as (max steps + 1)
|
|
|
track_data.resize(82); // TODO: setting as (max steps + 1)
|
|
|
|
|
|
|
|
|
struct inner_t { |
|
|
|
|
|
analyse_t *a; |
|
|
|
|
|
backtrack_t *b; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
std::queue<inner_t> track_cache; |
|
|
// TODO: for diff layer cases, layer_num from big to small -> if found then skip search
|
|
|
|
|
|
|
|
|
|
|
|
for (const auto &code : codes) { |
|
|
|
|
|
|
|
|
|
|
|
auto &cc = cases[code]; |
|
|
|
|
|
|
|
|
auto rt = track_data[81].emplace(code, backtrack_t { |
|
|
/// enlarge track_data
|
|
|
|
|
|
if (cc.step >= track_data.size()) { |
|
|
|
|
|
track_data.resize(cc.step + 1); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
track_cache.emplace(cache_t { |
|
|
|
|
|
.a = &cc, |
|
|
|
|
|
.b = &track_data[cc.step].emplace(code, backtrack_t { |
|
|
.code = code, |
|
|
.code = code, |
|
|
.layer_num = cases[code].step, |
|
|
.layer_num = cc.step, |
|
|
.last = std::list<backtrack_t*>{}, |
|
|
.last = std::list<backtrack_t*>{}, |
|
|
.next = std::list<backtrack_t*>{}, |
|
|
.next = std::list<backtrack_t*>{}, |
|
|
|
|
|
}).first->second, |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
/// start backtrack
|
|
|
} |
|
|
|
|
|
|
|
|
track_cache.emplace(inner_t { |
|
|
|
|
|
.a = &cases[code], |
|
|
|
|
|
.b = &rt.first->second, |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
while (!track_cache.front().a->src.empty()) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (!track_cache.empty()) { |
|
|
|
|
|
/// handle first element and pop it
|
|
|
auto curr = track_cache.front(); |
|
|
auto curr = track_cache.front(); |
|
|
|
|
|
for (auto src : curr.a->src) { // traverse src cases of current node
|
|
|
for (auto src : curr.a->src) { |
|
|
auto t_src = track_data[src->step].find(src->code); |
|
|
|
|
|
if (t_src != track_data[src->step].end()) { // match src case
|
|
|
auto find_ret = track_data[src->step].find(src->code); |
|
|
/// link (curr.b) and (t_src->second)
|
|
|
|
|
|
t_src->second.next.emplace_back(curr.b); |
|
|
if (find_ret != track_data[src->step].end()) { // found
|
|
|
curr.b->last.emplace_back(&t_src->second); |
|
|
|
|
|
} else { // src case not found
|
|
|
find_ret->second.next.emplace_back(curr.b); |
|
|
/// link (curr.b) and (t_src_new->second)
|
|
|
|
|
|
auto t_src_new = track_data[src->step].emplace(src->code, backtrack_t { |
|
|
curr.b->last.emplace_back(&find_ret->second); |
|
|
|
|
|
|
|
|
|
|
|
} else { // not found
|
|
|
|
|
|
|
|
|
|
|
|
// std::cout << "new: " << src->code << std::endl;
|
|
|
|
|
|
|
|
|
|
|
|
auto ret = track_data[src->step].emplace(src->code, backtrack_t { |
|
|
|
|
|
.code = src->code, |
|
|
.code = src->code, |
|
|
.layer_num = src->step, |
|
|
.layer_num = src->step, |
|
|
.last = std::list<backtrack_t*>{}, |
|
|
.last = std::list<backtrack_t*>{}, |
|
|
.next = std::list<backtrack_t*>{curr.b}, |
|
|
.next = std::list<backtrack_t*>{curr.b}, // link to curr.b
|
|
|
}); |
|
|
}).first; |
|
|
|
|
|
curr.b->last.emplace_back(&t_src_new->second); |
|
|
curr.b->last.emplace_back(&ret.first->second); |
|
|
/// insert into working queue
|
|
|
|
|
|
track_cache.emplace(cache_t { |
|
|
track_cache.emplace(inner_t { |
|
|
|
|
|
.a = src, |
|
|
.a = src, |
|
|
.b = &ret.first->second, |
|
|
.b = &t_src_new->second, |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
track_cache.pop(); |
|
|
track_cache.pop(); |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < track_data.size(); ++i) { |
|
|
for (uint32_t i = 0; i < track_data.size(); ++i) { |
|
|
|
|
|
|
|
|
const auto &ly = track_data[i]; |
|
|
const auto &ly = track_data[i]; |
|
@ -112,21 +105,16 @@ void Analyse::backtrack_demo(uint64_t code) { |
|
|
std::cout << "----------------------------------" << std::endl; |
|
|
std::cout << "----------------------------------" << std::endl; |
|
|
|
|
|
|
|
|
for (const auto &c : ly) { |
|
|
for (const auto &c : ly) { |
|
|
|
|
|
|
|
|
for (const auto &l : c.second.last) { |
|
|
for (const auto &l : c.second.last) { |
|
|
std::cout << l->code << " "; |
|
|
std::cout << l->code << " "; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
std::cout << " <- [" << c.second.code << "] -> "; |
|
|
std::cout << " <- [" << c.second.code << "] -> "; |
|
|
|
|
|
|
|
|
for (const auto &n : c.second.next) { |
|
|
for (const auto &n : c.second.next) { |
|
|
std::cout << n->code << " "; |
|
|
std::cout << n->code << " "; |
|
|
} |
|
|
} |
|
|
std::cout << std::endl; |
|
|
std::cout << std::endl; |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// std::cout << l.size() << std::endl;
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|