|
|
@ -3,6 +3,32 @@ |
|
|
|
using klotski::CommonCode; |
|
|
|
using klotski::CommonCodeException; |
|
|
|
|
|
|
|
/// -------------------------- CommonCode to String ---------------------------
|
|
|
|
|
|
|
|
std::string CommonCode::to_string(bool shorten) const { |
|
|
|
return string_encode(code, shorten); |
|
|
|
} |
|
|
|
|
|
|
|
/// -------------------------- String to CommonCode ---------------------------
|
|
|
|
|
|
|
|
CommonCode::CommonCode(std::string &&common_code) { |
|
|
|
code = string_decode(common_code); // load from string
|
|
|
|
} |
|
|
|
|
|
|
|
CommonCode::CommonCode(const std::string &common_code) { |
|
|
|
code = string_decode(common_code); // load from string
|
|
|
|
} |
|
|
|
|
|
|
|
CommonCode CommonCode::from_string(std::string &&common_code) { |
|
|
|
return CommonCode(std::forward<std::string>(common_code)); |
|
|
|
} |
|
|
|
|
|
|
|
CommonCode CommonCode::from_string(const std::string &common_code) { |
|
|
|
return CommonCode(common_code); |
|
|
|
} |
|
|
|
|
|
|
|
/// ----------------------------- Basic Functions -----------------------------
|
|
|
|
|
|
|
|
inline uint8_t binary_count(uint32_t bin) { // get number of non-zero bits
|
|
|
|
bin -= (bin >> 1) & 0x55'55'55'55; |
|
|
|
bin = (bin & 0x33'33'33'33) + ((bin >> 2) & 0x33'33'33'33); |
|
|
@ -18,28 +44,25 @@ inline uint8_t last_zero_num(uint32_t bin) { // get last zero number |
|
|
|
return binary_count(bin >> 1); |
|
|
|
} |
|
|
|
|
|
|
|
CommonCode CommonCode::from_string(const std::string &common_code) { |
|
|
|
return CommonCode(common_code); // load from string
|
|
|
|
} |
|
|
|
|
|
|
|
std::string CommonCode::to_string(bool shorten) const { // convert uint64_t code to string
|
|
|
|
std::string CommonCode::string_encode(uint64_t common_code, bool shorten) { // convert uint64_t code to string
|
|
|
|
char result[10]; // max length 9-bits
|
|
|
|
sprintf(result, "%09lX", code); |
|
|
|
sprintf(result, "%09lX", common_code); |
|
|
|
if (shorten) { // remove `0` after common code
|
|
|
|
if ((uint32_t)code == 0x00'00'00'00) { // low 32-bits are zero
|
|
|
|
if ((uint32_t)common_code == 0x00'00'00'00) { // low 32-bits are zero
|
|
|
|
result[1] = '\0'; // only keep first character
|
|
|
|
return result; |
|
|
|
} |
|
|
|
result[9 - last_zero_num(code) / 4] = '\0'; // truncate string
|
|
|
|
result[9 - last_zero_num(common_code) / 4] = '\0'; // truncate string
|
|
|
|
} |
|
|
|
return result; // char* -> std::string
|
|
|
|
} |
|
|
|
|
|
|
|
CommonCode::CommonCode(const std::string &common_code) { // convert from 1 ~ 9 bits string
|
|
|
|
uint64_t CommonCode::string_decode(const std::string &common_code) { // convert from 1 ~ 9 bits string
|
|
|
|
/// check string length
|
|
|
|
if (common_code.length() > 9 || common_code.empty()) { // check string length
|
|
|
|
throw CommonCodeException("common code should length 1 ~ 9"); |
|
|
|
} |
|
|
|
|
|
|
|
/// check every characters
|
|
|
|
uint64_t result = 0; |
|
|
|
for (auto const &bit : common_code) { |
|
|
@ -55,9 +78,10 @@ CommonCode::CommonCode(const std::string &common_code) { // convert from 1 ~ 9 b |
|
|
|
} |
|
|
|
} |
|
|
|
result <<= (9 - common_code.length()) * 4; // low-bits fill with zero
|
|
|
|
|
|
|
|
/// check whether common code is valid
|
|
|
|
if (!CommonCode::check(result)) { // check converted common code
|
|
|
|
throw CommonCodeException("common code invalid"); |
|
|
|
} |
|
|
|
code = result; |
|
|
|
return result; |
|
|
|
} |
|
|
|