From e3e07f2e31607a45660f3123dc656e3ddaaf565e Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sun, 8 Jan 2023 21:53:26 +0800 Subject: [PATCH] feat: tiny codec between short code and common code --- src/main.cc | 17 ++++--- src/short_code/CMakeLists.txt | 4 +- src/short_code/convert.cc | 50 +++++++++++++++++++ src/short_code/short_code.h | 6 +++ src/short_code/short_code_chars.h | 16 +++--- {klotski => src/short_code}/short_code_mark.h | 0 6 files changed, 74 insertions(+), 19 deletions(-) create mode 100644 src/short_code/convert.cc rename {klotski => src/short_code}/short_code_mark.h (100%) diff --git a/src/main.cc b/src/main.cc index d71133f..7ecf07f 100644 --- a/src/main.cc +++ b/src/main.cc @@ -97,13 +97,16 @@ int main() { // std::cout << ShortCode::check_mode() << std::endl; - auto s = ShortCode(14323231); -// auto s = ShortCode(14323231, ShortCode::NORMAL); -// auto s = ShortCode(14323231, ShortCode::FAST); - std::cout << s.unwrap() << std::endl; - std::cout << s.to_string() << std::endl; - std::cout << ShortCode("EP4HZ", ShortCode::NORMAL).unwrap() << std::endl; - std::cout << ShortCode("eP4hZ", ShortCode::FAST).to_string() << std::endl; +// auto s = ShortCode(14323231); +//// auto s = ShortCode(14323231, ShortCode::NORMAL); +//// auto s = ShortCode(14323231, ShortCode::FAST); +// std::cout << s.unwrap() << std::endl; +// std::cout << s.to_string() << std::endl; +// std::cout << ShortCode("EP4HZ", ShortCode::NORMAL).unwrap() << std::endl; +// std::cout << ShortCode("eP4hZ", ShortCode::FAST).to_string() << std::endl; + + std::cout << ShortCode::tiny_encode(0x6EC0F8800) << std::endl; + printf("%09lX\n", ShortCode::tiny_decode(14323231)); return 0; } diff --git a/src/short_code/CMakeLists.txt b/src/short_code/CMakeLists.txt index 1486ddb..4ff6086 100644 --- a/src/short_code/CMakeLists.txt +++ b/src/short_code/CMakeLists.txt @@ -1,4 +1,4 @@ cmake_minimum_required(VERSION 3.0) -add_library(short_code data_loader.cc short_code.cc) -target_link_libraries(short_code all_cases) +add_library(short_code convert.cc short_code.cc data_loader.cc) +target_link_libraries(short_code common all_cases) diff --git a/src/short_code/convert.cc b/src/short_code/convert.cc new file mode 100644 index 0000000..48d1e44 --- /dev/null +++ b/src/short_code/convert.cc @@ -0,0 +1,50 @@ +#include "common.h" +#include "short_code.h" +#include "basic_ranges.h" +#include "short_code_mark.h" + +uint32_t ShortCode::tiny_encode(uint64_t common_code) { // common_code --low-memory--> short_code + uint32_t offset = 0; + uint32_t head = common_code >> 32; // common code head + uint32_t prefix = (common_code >> 24) & 0xFF; // common code range prefix + auto target = Common::range_reverse((uint32_t)common_code); // target range + + for (int index = 0; index < BASIC_RANGES_INDEX[prefix]; ++index) { // traverse basic ranges + uint32_t range = (*BasicRanges::fetch())[index + BASIC_RANGES_OFFSET[prefix]]; + if (range == target) { + break; // found target range + } + if (Common::check_case(head, range)) { // search for valid cases + ++offset; // record sub offset + } + } + return ALL_CASES_OFFSET[head] + RANGE_PREFIX_OFFSET[head][prefix] + offset; +} + +uint64_t ShortCode::tiny_decode(uint32_t short_code) { // short_code --low-memory--> common_code + uint32_t head = 0, prefix = 0; + for (; head < 16; ++head) { + if (short_code < ALL_CASES_INDEX[head]) { // match head + break; + } + short_code -= ALL_CASES_INDEX[head]; // short code approximate + } + for (; prefix < 256; ++prefix) { + if (short_code < RANGE_PREFIX_INDEX[head][prefix]) { // match range prefix + break; + } + short_code -= RANGE_PREFIX_INDEX[head][prefix]; // short code approximate + } + + uint32_t range; + for (int index = 0; index < BASIC_RANGES_INDEX[prefix]; ++index) { // traverse basic ranges + range = (*BasicRanges::fetch())[index + BASIC_RANGES_OFFSET[prefix]]; + if (Common::check_case(head, range)) { // search for valid cases + if (short_code == 0) { + break; // found target range + } + --short_code; // short code approximate + } + } + return (uint64_t)head << 32 | Common::range_reverse(range); // release common code +} diff --git a/src/short_code/short_code.h b/src/short_code/short_code.h index 60b9822..16037e8 100644 --- a/src/short_code/short_code.h +++ b/src/short_code/short_code.h @@ -26,6 +26,9 @@ public: speed_up(mode); } + static uint64_t tiny_decode(uint32_t short_code); + static uint32_t tiny_encode(uint64_t common_code); + private: uint32_t code; static std::mutex map_building; @@ -36,4 +39,7 @@ private: static std::unordered_map all_cases_dict; // common_code -> short_code static void build_mappings(); + +// static uint64_t tiny_decode(uint32_t short_code); +// static uint32_t tiny_encode(uint64_t common_code); }; diff --git a/src/short_code/short_code_chars.h b/src/short_code/short_code_chars.h index cb4b748..6d1def7 100644 --- a/src/short_code/short_code_chars.h +++ b/src/short_code/short_code_chars.h @@ -8,15 +8,11 @@ const char SHORT_CODE_TABLE[32] = { 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', }; +/// `1`(49) ~ `Z`(90) const char SHORT_CODE_TABLE_REV[42] = { -// 00 01 02 03 04 05 06 07 08 - 0, 1, 2, 3, 4, 5, 6, 7, 8, -// 09 10 11 12 13 14 15 - -1, -1, -1, -1, -1, -1, -1, -// 16 17 18 19 20 21 22 23 24 25 - 9, 10, 11, 12, 13, 14, 15, 16, -1, 17, -// 26 27 28 29 30 31 32 33 34 35 - 18, -1, 19, 20, -1, 21, 22, 23, 24, 25, -// 36 37 38 39 40 41 - 26, 27, 28, 29, 30, 31, + 0, 1, 2, 3, 4, 5, 6, 7, 8, // `1`(49) ~ `9`(57) + -1, -1, -1, -1, -1, -1, -1, // `:`(58) ~ `@`(64) + 9, 10, 11, 12, 13, 14, 15, 16, -1, 17, // `A`(65) ~ `J`(74) + 18, -1, 19, 20, -1, 21, 22, 23, 24, 25, // `K`(75) ~ `T`(84) + 26, 27, 28, 29, 30, 31, // `U`(85) ~ `Z`(90) }; diff --git a/klotski/short_code_mark.h b/src/short_code/short_code_mark.h similarity index 100% rename from klotski/short_code_mark.h rename to src/short_code/short_code_mark.h