diff --git a/klotski/main.cc b/klotski/main.cc index d4d77e2..e243018 100644 --- a/klotski/main.cc +++ b/klotski/main.cc @@ -18,7 +18,7 @@ int main() { // } // auto s = ShortCode(); - auto s = ShortCode(ShortCode::Mode::NORMAL); +// auto s = ShortCode(ShortCode::Mode::NORMAL); // auto s = ShortCode(ShortCode::Mode::FAST); // s.speed_up(ShortCode::Mode::FAST); @@ -29,7 +29,12 @@ int main() { // printf("%09lX\n", s.fast_decode(14323231)); // s.speed_up(ShortCode::Mode::NORMAL); - std::cout << s.basic_ranges.size() << std::endl; +// std::cout << s.basic_ranges.size() << std::endl; + + auto s = ShortCode(); + s.speed_up(ShortCode::Mode::NORMAL); // enter normal mode first + + printf("%09lX\n", s.tiny_decode(14323231)); return 0; } diff --git a/klotski/short_code.cc b/klotski/short_code.cc index 3997bee..edb61c3 100644 --- a/klotski/short_code.cc +++ b/klotski/short_code.cc @@ -1,3 +1,4 @@ +#include "common.h" #include "all_cases.h" #include "short_code.h" #include "short_code_mark.h" @@ -39,12 +40,42 @@ void ShortCode::build_mappings() { // build fast search mappings } } -uint64_t ShortCode::fast_decode(uint32_t short_code) { // short_code -> common_code +uint64_t ShortCode::fast_decode(uint32_t short_code) { // short_code --fast--> common_code // TODO: ensure input short_code < SHORT_CODE_LIMIT return all_cases_list[short_code]; } -uint32_t ShortCode::fast_encode(uint64_t common_code) { // common_code -> short_code +uint32_t ShortCode::fast_encode(uint64_t common_code) { // common_code --fast--> short_code // TODO: ensure input common_code valid return all_cases_dict[common_code]; } + +// TODO: load basic ranges before tiny_decode +// TODO: ensure input short_code < SHORT_CODE_LIMIT +uint64_t ShortCode::tiny_decode(uint32_t short_code) { // short_code --low-mem--> 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 = basic_ranges[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 +}