mirror of https://github.com/dnomd343/klotski.git
Dnomd343
2 years ago
6 changed files with 74 additions and 19 deletions
@ -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) |
|||
|
@ -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
|
|||
} |
Loading…
Reference in new issue