Browse Source

update: add interface of Analyse backtrack

master
Dnomd343 2 years ago
parent
commit
7e56e8a4e4
  1. 2
      src/analyse/CMakeLists.txt
  2. 15
      src/analyse/analyse.h
  3. 209
      src/analyse/backtrack.cc
  4. 184
      src/analyse/backtrack_legacy.cc
  5. 21
      src/main.cc

2
src/analyse/CMakeLists.txt

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0)
add_library(analyse analyse.cc)
add_library(analyse analyse.cc backtrack.cc)
target_link_libraries(analyse core)

15
src/analyse/analyse.h

@ -8,6 +8,7 @@
#include "core.h"
#include "raw_code.h"
// TODO: try double or 4-times size
const uint32_t ANY_MAP_RESERVE = 65536;
class Analyse {
@ -42,6 +43,20 @@ private:
void new_case(uint64_t code, uint64_t mask);
public:
struct backtrack_t {
uint64_t code;
uint32_t layer_num;
std::list<backtrack_t*> last;
std::list<backtrack_t*> next;
// bool operator==(const backtrack_t &b) const {
// return b.code == code;
// }
};
void backtrack_demo(uint64_t code);
/// backtrack definitions
// struct backtrack_t {

209
src/analyse/backtrack.cc

@ -1,183 +1,80 @@
#include "analyse.h"
void dump_python_case(uint64_t raw_code) {
std::string result;
for (int addr = 0; raw_code; ++addr, raw_code >>= 3) {
uint32_t x = addr % 4;
uint32_t y = (addr - x) / 4;
char block[11]; // eg: `[0,0,1,1]`
switch (raw_code & 0b111) {
case B_1x1:
sprintf(block, "[%d,%d,1,1],", x, y);
result += block;
break;
case B_1x2:
sprintf(block, "[%d,%d,1,2],", x, y);
result += block;
break;
case B_2x1:
sprintf(block, "[%d,%d,2,1],", x, y);
result += block;
break;
case B_2x2:
sprintf(block, "[%d,%d,2,2],", x, y);
result += block;
break;
default:
continue;
}
}
result[result.length() - 1] = '\0'; // remove last `,`
std::cout << '[' << result.c_str() << ']';
}
void Analyse::backtrack(const std::vector<uint64_t> &raw_code_list) {
// backtrack start at code
// std::cout << "start backtrack" << std::endl;
std::queue<analyse_t*> track_cache;
#include <iostream>
std::vector<std::vector<backtrack_t*> > layer_data;
#include <set>
#include <unordered_set>
std::unordered_map<uint64_t, backtrack_t> track_data;
// TODO: confirm that code exist
/// layer init
// auto max_step = cases[code].step; // TODO: update max step cal
// auto max_step = 81;
uint32_t max_step = 0;
for (const auto &code : raw_code_list) {
// TODO: check whether cases include code
if (cases[code].step > max_step) {
max_step = cases[code].step;
}
}
// TODO: using const RawCode& instead of uint64_t
layer_data.resize(max_step + 1);
/// init track begin cases
// {
// auto layer_num = cases[code].step;
//
// track_cache.emplace(&cases[code]);
//
// auto ptr = track_data.emplace(code, backtrack_t {
// .code = code,
// .layer_num = layer_num,
// .layer_index = (uint32_t)layer_data[layer_num].size(),
// });
//
// layer_data[layer_num].emplace_back(&ptr.first->second);
struct backtrack_hash {
// template <class T1, class T2>
// std::size_t operator()(const std::pair<T1, T2> &v) const {
// return std::hash<T1>()(v.size());
// }
for (auto code : raw_code_list) {
std::size_t operator()(const Analyse::backtrack_t &b) const {
std::cout << "hash -> " << b.code << std::endl;
auto layer_num = cases[code].step;
auto hash_ret = std::hash<uint64_t>()(b.code);
track_cache.emplace(&cases[code]);
std::cout << "hash ret -> " << hash_ret << std::endl;
auto ptr = track_data.emplace(code, backtrack_t {
.code = code,
.layer_num = layer_num,
.layer_index = (uint32_t)layer_data[layer_num].size(),
});
layer_data[layer_num].emplace_back(&ptr.first->second);
return b.code;
}
// for (const auto &t : track_data) {
// std::cout << RawCode(t.second.code).dump_case() << std::endl;
// std::cout << t.second.layer_num << " " << t.second.layer_index << std::endl;
// }
};
while (!track_cache.front()->src.empty()) {
void Analyse::backtrack_demo(uint64_t code) {
auto current = track_cache.front();
// std::cout << RawCode(code) << std::endl;
for (auto src : current->src) {
// TODO: confirm code exist
std::cout << cases[code].step << std::endl;
auto find_ret = track_data.find(src->code);
if (find_ret != track_data.end()) { // already exist
std::string str("demo");
std::hash<std::string> str_hash;
std::cout << "hash str -> " << str_hash(str) << std::endl;
find_ret->second.next.emplace_back(
&track_data[current->code]
);
int i = 123;
std::hash<int> int_hash;
std::cout << "hash int -> " << int_hash(i) << std::endl;
} else { // insert new case
// std::vector<std::unordered_set<backtrack_t>> dat;
track_cache.emplace(src);
auto b_hash = [](const backtrack_t &b) {
std::cout << "get hash: " << b.code << std::endl;
return (std::size_t)666;
};
auto ptr = track_data.emplace(src->code, backtrack_t {
.code = src->code,
.layer_num = src->step,
.layer_index = (uint32_t)layer_data[src->step].size(),
.next = std::list<backtrack_t*>{&track_data[current->code]},
});
auto b_eq = [](const backtrack_t &b1, const backtrack_t &b2) {
std::cout << "get eq: " << b1.code << " ? " << b2.code << std::endl;
return b1.code == b2.code;
};
layer_data[src->step].emplace_back(&ptr.first->second);
std::unordered_set<backtrack_t, decltype(b_hash), decltype(b_eq)> test(10, b_hash, b_eq);
}
test.emplace(backtrack_t {
.code = 123,
.layer_num = 0,
.last = std::list<backtrack_t*>{},
.next = std::list<backtrack_t*>{},
});
}
track_cache.pop();
test.emplace(backtrack_t {
.code = 233,
.layer_num = 1,
.last = std::list<backtrack_t*>{},
.next = std::list<backtrack_t*>{},
});
}
backtrack_t *root = &track_data[track_cache.front()->code];
// std::cout << "Size = " << track_data.size() << std::endl;
// std::cout << "Root" << std::endl;
// std::cout << RawCode(root->code).dump_case() << std::endl;
// for (auto layer : layer_data) {
// std::cout << "-----------------------" << std::endl;
// std::cout << "layer size = " << layer.size() << std::endl;
//
// for (auto element : layer) {
// std::cout << "(" << element->layer_num << ", " << element->layer_index << ") -> ";
// for (auto next : element->next) {
// std::cout << "(" << next->layer_num << ", " << next->layer_index << ") ";
// }
// std::cout << std::endl;
//
// std::cout << RawCode(element->code).dump_case() << std::endl;
// }
// }
printf("layer:\n");
for (uint32_t num = 0; num < layer_data.size(); ++num) {
auto layer = &layer_data[num];
printf("- [");
for (auto element : *layer) {
// printf(&",\"%015lX\""[element == (*layer)[0]], element->code);
printf("%s", &","[element == (*layer)[0]]);
dump_python_case(element->code);
}
printf("] # layer %d\n", num);
}
printf("\n");
printf("next:\n");
for (uint32_t num = 0; num + 1 < layer_data.size(); ++num) {
auto layer = &layer_data[num];
printf("- ");
for (uint32_t index = 0; index < layer->size(); ++index) {
auto element = &(*layer)[index];
printf("%s", &" - ["[!index * 2]);
bool first_flag = true;
for (auto next : (*element)->next) {
printf(&",%d"[first_flag], next->layer_index);
if (first_flag) { first_flag = false; }
}
printf("] # (%d, %d) -> %d\n", num, index, num + 1);
}
}
test.emplace(backtrack_t {
.code = 343,
.layer_num = 2,
.last = std::list<backtrack_t*>{},
.next = std::list<backtrack_t*>{},
});

184
src/analyse/backtrack_legacy.cc

@ -0,0 +1,184 @@
void dump_python_case(uint64_t raw_code) {
std::string result;
for (int addr = 0; raw_code; ++addr, raw_code >>= 3) {
uint32_t x = addr % 4;
uint32_t y = (addr - x) / 4;
char block[11]; // eg: `[0,0,1,1]`
switch (raw_code & 0b111) {
case B_1x1:
sprintf(block, "[%d,%d,1,1],", x, y);
result += block;
break;
case B_1x2:
sprintf(block, "[%d,%d,1,2],", x, y);
result += block;
break;
case B_2x1:
sprintf(block, "[%d,%d,2,1],", x, y);
result += block;
break;
case B_2x2:
sprintf(block, "[%d,%d,2,2],", x, y);
result += block;
break;
default:
continue;
}
}
result[result.length() - 1] = '\0'; // remove last `,`
std::cout << '[' << result.c_str() << ']';
}
void Analyse::backtrack(const std::vector<uint64_t> &raw_code_list) {
// backtrack start at code
// std::cout << "start backtrack" << std::endl;
std::queue<analyse_t*> track_cache;
std::vector<std::vector<backtrack_t*> > layer_data;
std::unordered_map<uint64_t, backtrack_t> track_data;
// TODO: confirm that code exist
/// layer init
// auto max_step = cases[code].step; // TODO: update max step cal
// auto max_step = 81;
uint32_t max_step = 0;
for (const auto &code : raw_code_list) {
// TODO: check whether cases include code
if (cases[code].step > max_step) {
max_step = cases[code].step;
}
}
layer_data.resize(max_step + 1);
/// init track begin cases
// {
// auto layer_num = cases[code].step;
//
// track_cache.emplace(&cases[code]);
//
// auto ptr = track_data.emplace(code, backtrack_t {
// .code = code,
// .layer_num = layer_num,
// .layer_index = (uint32_t)layer_data[layer_num].size(),
// });
//
// layer_data[layer_num].emplace_back(&ptr.first->second);
// }
for (auto code : raw_code_list) {
auto layer_num = cases[code].step;
track_cache.emplace(&cases[code]);
auto ptr = track_data.emplace(code, backtrack_t {
.code = code,
.layer_num = layer_num,
.layer_index = (uint32_t)layer_data[layer_num].size(),
});
layer_data[layer_num].emplace_back(&ptr.first->second);
}
// for (const auto &t : track_data) {
// std::cout << RawCode(t.second.code).dump_case() << std::endl;
// std::cout << t.second.layer_num << " " << t.second.layer_index << std::endl;
// }
while (!track_cache.front()->src.empty()) {
auto current = track_cache.front();
for (auto src : current->src) {
auto find_ret = track_data.find(src->code);
if (find_ret != track_data.end()) { // already exist
find_ret->second.next.emplace_back(
&track_data[current->code]
);
} else { // insert new case
track_cache.emplace(src);
auto ptr = track_data.emplace(src->code, backtrack_t {
.code = src->code,
.layer_num = src->step,
.layer_index = (uint32_t)layer_data[src->step].size(),
.next = std::list<backtrack_t*>{&track_data[current->code]},
});
layer_data[src->step].emplace_back(&ptr.first->second);
}
}
track_cache.pop();
}
backtrack_t *root = &track_data[track_cache.front()->code];
// std::cout << "Size = " << track_data.size() << std::endl;
// std::cout << "Root" << std::endl;
// std::cout << RawCode(root->code).dump_case() << std::endl;
// for (auto layer : layer_data) {
// std::cout << "-----------------------" << std::endl;
// std::cout << "layer size = " << layer.size() << std::endl;
//
// for (auto element : layer) {
// std::cout << "(" << element->layer_num << ", " << element->layer_index << ") -> ";
// for (auto next : element->next) {
// std::cout << "(" << next->layer_num << ", " << next->layer_index << ") ";
// }
// std::cout << std::endl;
//
// std::cout << RawCode(element->code).dump_case() << std::endl;
// }
// }
printf("layer:\n");
for (uint32_t num = 0; num < layer_data.size(); ++num) {
auto layer = &layer_data[num];
printf("- [");
for (auto element : *layer) {
// printf(&",\"%015lX\""[element == (*layer)[0]], element->code);
printf("%s", &","[element == (*layer)[0]]);
dump_python_case(element->code);
}
printf("] # layer %d\n", num);
}
printf("\n");
printf("next:\n");
for (uint32_t num = 0; num + 1 < layer_data.size(); ++num) {
auto layer = &layer_data[num];
printf("- ");
for (uint32_t index = 0; index < layer->size(); ++index) {
auto element = &(*layer)[index];
printf("%s", &" - ["[!index * 2]);
bool first_flag = true;
for (auto next : (*element)->next) {
printf(&",%d"[first_flag], next->layer_index);
if (first_flag) { first_flag = false; }
}
printf("] # (%d, %d) -> %d\n", num, index, num + 1);
}
}
}

21
src/main.cc

@ -41,7 +41,7 @@ int main() {
// sleep(3);
// std::cout << "start benchmark" << std::endl;
// auto start_time = clock();
auto start_time = clock();
// {
@ -54,18 +54,21 @@ int main() {
auto a = Analyse(RawCode::from_common_code("1a9bf0c"));
a.build();
// auto ret = a.build_until([](uint64_t code) {
// return ((code >> (3 * 0xD)) & 0b111) == B_2x2;
// });
// a.build();
auto ret = a.build_until([](uint64_t code) {
return ((code >> (3 * 0xD)) & 0b111) == B_2x2;
});
// for (const auto &r : ret) {
// std::cout << r << std::endl;
// }
auto start_time = clock();
a.backtrack_demo(0x7F87E0E5BFFF492);
// a.backtrack_demo(0x1FB1E36F9FFF492);
// auto start_time = clock();
std::cout << a.layer_export(81).size() << std::endl;
std::cout << a.layer_export()[81].size() << std::endl;
// std::cout << a.layer_export(81).size() << std::endl;
// std::cout << a.layer_export()[81].size() << std::endl;
// auto raw_code = CommonCode("A5D3AF0").to_raw_code().unwrap();
@ -108,7 +111,7 @@ int main() {
// std::cerr << (clock() - start_time) * 1000 / CLOCKS_PER_SEC << "ms" << std::endl;
std::cerr << (clock() - start_time) * 1000000 / CLOCKS_PER_SEC << "us" << std::endl;
std::cout << "complete benchmark" << std::endl;
// std::cout << "complete benchmark" << std::endl;
// pause();

Loading…
Cancel
Save