diff --git a/src/common_code/common_code.cc b/src/common_code/common_code.cc index b3a7870..5a2c0cb 100644 --- a/src/common_code/common_code.cc +++ b/src/common_code/common_code.cc @@ -117,3 +117,68 @@ bool CommonCode::check(uint64_t common_code) { // check whether common code is v } return Common::check_case(head, range); // check by head and range } + +#include + +bool CommonCode::check_demo(uint64_t common_code) { + /// M_1x1 M_1x2 M_2x1 M_2x2 + /// 1 0 0 0 1 1 0 0 1 0 0 0 1 1 0 0 + /// 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 + /// ... ... ... ... + constexpr uint32_t M_1x1 = 0b1; + constexpr uint32_t M_1x2 = 0b11; + constexpr uint32_t M_2x1 = 0b10001; + constexpr uint32_t M_2x2 = 0b110011; + + /// 2x2 address check (high 32-bits) + uint32_t head = common_code >> 32; + if (head >= 16 || (head & 0b11) == 0b11) { // check 2x2 block address + return false; // invalid common code + } + + auto range = Common::range_reverse((uint32_t)common_code); + + uint32_t mask = M_2x2 << head; // fill 2x2 block + + int space_num = 0; + for (int addr = 0;; range >>= 2) { // traverse every 2-bits + + + while (mask >> addr & 0b1) { + ++addr; // search next unfilled block + } + if (addr >= 20) { + return range == 0 && space_num > 1; + } + +// std::cout << "addr = " << addr; +// std::cout << " | block = " << (range & 0b11) << std::endl; + + // FEA13400 -> 1111 1110 1010 0001 0011 0100 0000 0000 + // * * * | + // # + | + + // + + + | + // . ~ + + + // . * ~ + + + switch (range & 0b11) { + case 0b00: // space + ++space_num; + case 0b11: // 1x1 block + mask |= M_1x1 << addr; // fill space or 1x1 block + break; + case 0b10: // 2x1 block + if (addr > 15 || mask >> (addr + 4) & 0b1) { // invalid address + return false; + } + mask |= M_2x1 << addr; // fill 2x1 block + break; + case 0b01: // 1x2 block + if (addr > 18 || (addr & 0b11) == 0b11 || mask >> (addr + 1) & 0b1) { // invalid address + return false; + } + mask |= M_1x2 << addr; // fill 1x2 block + break; + } + } +} diff --git a/src/common_code/common_code.h b/src/common_code/common_code.h index ebb9679..14006c6 100644 --- a/src/common_code/common_code.h +++ b/src/common_code/common_code.h @@ -14,6 +14,8 @@ public: static bool check(uint64_t common_code); static CommonCode unsafe_create(uint64_t code); + static bool check_demo(uint64_t common_code); + RawCode to_raw_code() const; ShortCode to_short_code() const; std::string to_string(bool shorten = false) const; diff --git a/src/main.cc b/src/main.cc index 21d6185..75b71fa 100644 --- a/src/main.cc +++ b/src/main.cc @@ -71,33 +71,33 @@ void short_code_verify(uint32_t start, uint32_t end) { int main() { - AllCases::build(); - - for (uint64_t head = 0; head < 16; ++head) { - for (const auto &range : AllCases::fetch()[head]) { - all_cases.emplace_back(head << 32 | range); - } - } - - ShortCode::speed_up(ShortCode::NORMAL); - std::cout << "start verify" << std::endl; - -// auto start_time = clock(); - - std::thread tasks[16]; - - for (int head = 0; head < 16; ++head) { - uint32_t start = ALL_CASES_OFFSET[head]; - uint32_t end = start + AllCases::fetch()[head].size(); - tasks[head] = std::thread(short_code_verify, start, end); - } - - for (auto &t : tasks) { - t.join(); - } - - std::cout << "verify complete" << std::endl; - return 0; +// AllCases::build(); +// +// for (uint64_t head = 0; head < 16; ++head) { +// for (const auto &range : AllCases::fetch()[head]) { +// all_cases.emplace_back(head << 32 | range); +// } +// } +// +// ShortCode::speed_up(ShortCode::NORMAL); +// std::cout << "start verify" << std::endl; +// + auto start_time = clock(); +// +// std::thread tasks[16]; +// +// for (int head = 0; head < 16; ++head) { +// uint32_t start = ALL_CASES_OFFSET[head]; +// uint32_t end = start + AllCases::fetch()[head].size(); +// tasks[head] = std::thread(short_code_verify, start, end); +// } +// +// for (auto &t : tasks) { +// t.join(); +// } +// +// std::cout << "verify complete" << std::endl; +// return 0; @@ -335,8 +335,23 @@ int main() { // std::cout << sizeof(ShortCode) << std::endl; +// int sum = 0; + for (uint64_t common_code = 0; common_code < 0x100000000; ++common_code) { +// if (CommonCode::check_demo(common_code)) { +// ++sum; +// } + if (CommonCode::check(common_code) != CommonCode::check_demo(common_code)) { + printf("%09lX\n", common_code); + } + } +// std::cout << "sum = " << sum << std::endl; + +// std::cout << CommonCode::check_demo(0x4FEA13400) << std::endl; +// std::cout << CommonCode::check_demo(0x0000011CE) << std::endl; +// std::cout << CommonCode::check_demo(0x02ED67000) << std::endl; + // 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::cerr << (clock() - start_time) * 1000000 / CLOCKS_PER_SEC << "us" << std::endl; // std::cout << "complete benchmark" << std::endl; // pause();