From 58915c4d5d6ee0ccd0862e223cd81e0cbbdf77ca Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Fri, 6 Jan 2023 19:14:11 +0800 Subject: [PATCH] feat: short code from string --- klotski/main.cc | 1 + klotski/short_code.cc | 32 +++++++++++++++++++++++++++++++- klotski/short_code.h | 32 ++++++++++++++++++++------------ 3 files changed, 52 insertions(+), 13 deletions(-) diff --git a/klotski/main.cc b/klotski/main.cc index 42aa8c0..b0fe356 100644 --- a/klotski/main.cc +++ b/klotski/main.cc @@ -63,6 +63,7 @@ int main() { std::cout << ShortCode::code_to_string(14323231) << std::endl; + std::cout << ShortCode::code_from_string("EP4HZ") << std::endl; return 0; } diff --git a/klotski/short_code.cc b/klotski/short_code.cc index a4e61dc..a97ba91 100644 --- a/klotski/short_code.cc +++ b/klotski/short_code.cc @@ -13,7 +13,7 @@ bool ShortCode::check(uint32_t short_code) { return short_code < ShortCode::SHORT_CODE_LIMIT; // 0 ~ (SHORT_CODE_LIMIT - 1) } -std::string ShortCode::code_to_string(uint32_t short_code) { +std::string ShortCode::code_to_string(uint32_t short_code) { // encode as 5-bits string if (!ShortCode::check(short_code)) { throw std::range_error("short code out of range"); } @@ -26,6 +26,36 @@ std::string ShortCode::code_to_string(uint32_t short_code) { return result; } +uint32_t ShortCode::code_from_string(const std::string &short_code) { // 5-bits string decode as number + if (short_code.length() != 5) { + throw std::runtime_error("invalid short code"); + } + uint32_t result = 0; + for (auto bit : short_code) { + result *= 32; + if (bit >= '1' && bit <= '9') { // 1 ~ 9 + result += bit - 49; + continue; + } + if (bit >= 'a' && bit <= 'z') { // a ~ z + bit -= ('a' - 'A'); // convert to A ~ Z + } + if (bit >= 'A' && bit <= 'Z') { // A ~ Z + bit = SHORT_CODE_TABLE_REV[bit - 65]; // table convert + if (bit == 0) { + throw std::runtime_error("invalid short code"); + } + result += bit; + } else { + throw std::runtime_error("invalid short code"); + } + } + if (!ShortCode::check(result)) { + throw std::range_error("short code out of range"); + } + return result; +} + void ShortCode::speed_up(enum Mode mode) { // speed up handle short code switch (mode) { case Mode::NORMAL: // speed up into normal mode diff --git a/klotski/short_code.h b/klotski/short_code.h index d5715fa..1cd6ca9 100644 --- a/klotski/short_code.h +++ b/klotski/short_code.h @@ -11,20 +11,28 @@ const char SHORT_CODE_TABLE[32] = { 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', }; -// 1 -> 48 -// ... -// 9 -> 57 -// A -> 65 +const char SHORT_CODE_TABLE_REV[26] = { +// 00 01 02 03 04 05 06 07 08 09 + 9, 10, 11, 12, 13, 14, 15, 16, 0, 17, +// 10 11 12 13 14 15 16 17 18 19 + 18, 0, 19, 20, 0, 21, 22, 23, 24, 25, +// 20 21 22 23 24 25 + 26, 27, 28, 29, 30, 31, +}; + +// 00: 1 -> 48 // ... -// H -> 72 -// J -> 74 +// 08: 9 -> 57 +// 09: A -> 65 (00) // ... -// K -> 75 -// M -> 77 -// N -> 78 -// P -> 80 +// 16: H -> 72 (07) +// 17: J -> 74 (09) +// 18: K -> 75 (10) +// 19: M -> 77 (12) +// 20: N -> 78 (13) +// 21: P -> 80 (15) // ... -// Z -> 90 +// 31: Z -> 90 (25) class ShortCode { public: @@ -39,7 +47,7 @@ public: uint64_t unzip_short_code(uint32_t short_code); static std::string code_to_string(uint32_t short_code); -// static uint32_t code_from_string(const std::string &short_code); + static uint32_t code_from_string(const std::string &short_code); private: static const uint32_t SHORT_CODE_LIMIT = 29334498;