Browse Source

feat: mirror functions of CommonCode

master
Dnomd343 3 months ago
parent
commit
75df4e536b
  1. 27
      src/core/common_code/common_code.h
  2. 36
      src/core/common_code/internal/common_code.inl
  3. 38
      src/core/common_code/internal/mirror.cc
  4. 28
      src/core/main.cc

27
src/core/common_code/common_code.h

@ -139,6 +139,20 @@ public:
// ------------------------------------------------------------------------------------- // // ------------------------------------------------------------------------------------- //
/// Whether the layout is vertically symmetrical.
[[nodiscard]] bool is_vertical_mirror() const;
/// Whether the layout is horizontally symmetrical.
[[nodiscard]] bool is_horizontal_mirror() const;
/// Calculate the vertically symmetrical klotski layout.
[[nodiscard]] CommonCode to_vertical_mirror() const;
/// Calculate the horizontally symmetrical klotski layout.
[[nodiscard]] CommonCode to_horizontal_mirror() const;
// ------------------------------------------------------------------------------------- //
/// Compare CommonCode with u64 value. /// Compare CommonCode with u64 value.
friend constexpr auto operator==(const CommonCode &lhs, uint64_t rhs); friend constexpr auto operator==(const CommonCode &lhs, uint64_t rhs);
friend constexpr auto operator<=>(const CommonCode &lhs, uint64_t rhs); friend constexpr auto operator<=>(const CommonCode &lhs, uint64_t rhs);
@ -149,8 +163,6 @@ public:
// ------------------------------------------------------------------------------------- // // ------------------------------------------------------------------------------------- //
static bool is_mirror(uint64_t common_code);
private: private:
uint64_t code_; uint64_t code_;
@ -166,6 +178,17 @@ private:
static std::optional<uint64_t> string_decode(std::string_view common_code); static std::optional<uint64_t> string_decode(std::string_view common_code);
// ------------------------------------------------------------------------------------- // // ------------------------------------------------------------------------------------- //
/// Check the horizontally symmetrical.
static bool check_mirror(uint64_t common_code);
/// Get the vertically symmetrical layout.
static uint64_t get_vertical_mirror(uint64_t common_code);
/// Get the horizontally symmetrical layout.
static uint64_t get_horizontal_mirror(uint64_t common_code);
// ------------------------------------------------------------------------------------- //
}; };
static_assert(std::is_standard_layout_v<CommonCode>); static_assert(std::is_standard_layout_v<CommonCode>);

36
src/core/common_code/internal/common_code.inl

@ -1,13 +1,11 @@
#pragma once #pragma once
#include <bit>
#include "raw_code/raw_code.h" #include "raw_code/raw_code.h"
#include "short_code/short_code.h" #include "short_code/short_code.h"
namespace klotski::codec { namespace klotski::codec {
// ------------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------------- //
inline CommonCode::CommonCode(const RawCode raw_code) { inline CommonCode::CommonCode(const RawCode raw_code) {
code_ = raw_code.to_common_code().code_; code_ = raw_code.to_common_code().code_;
@ -28,7 +26,7 @@ inline std::optional<CommonCode> CommonCode::create(const uint64_t common_code)
return unsafe_create(common_code); return unsafe_create(common_code);
} }
// ------------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------------- //
inline CommonCode::operator uint64_t() const { inline CommonCode::operator uint64_t() const {
return code_; return code_;
@ -41,7 +39,7 @@ inline std::ostream& operator<<(std::ostream &out, const CommonCode self) {
} }
#endif #endif
// ------------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------------- //
inline uint64_t CommonCode::unwrap() const { inline uint64_t CommonCode::unwrap() const {
return code_; return code_;
@ -62,13 +60,13 @@ inline std::string CommonCode::to_string(const bool shorten) const {
return string_encode_shorten(code_); // without trailing zero return string_encode_shorten(code_); // without trailing zero
} }
// ------------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------------- //
inline std::optional<CommonCode> CommonCode::from_string(const std::string_view common_code) { inline std::optional<CommonCode> CommonCode::from_string(const std::string_view common_code) {
return string_decode(common_code).transform(unsafe_create); return string_decode(common_code).transform(unsafe_create);
} }
// ------------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------------- //
inline CommonCode CommonCode::from_raw_code(const RawCode raw_code) { inline CommonCode CommonCode::from_raw_code(const RawCode raw_code) {
return raw_code.to_common_code(); return raw_code.to_common_code();
@ -81,7 +79,7 @@ inline std::optional<CommonCode> CommonCode::from_raw_code(const uint64_t raw_co
return RawCode::create(raw_code).transform(convert); return RawCode::create(raw_code).transform(convert);
} }
// ------------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------------- //
inline CommonCode CommonCode::from_short_code(const ShortCode short_code) { inline CommonCode CommonCode::from_short_code(const ShortCode short_code) {
return short_code.to_common_code(); return short_code.to_common_code();
@ -101,7 +99,25 @@ inline std::optional<CommonCode> CommonCode::from_short_code(const std::string_v
return ShortCode::from_string(short_code).transform(convert); return ShortCode::from_string(short_code).transform(convert);
} }
// ------------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------------- //
inline bool CommonCode::is_vertical_mirror() const {
return false;
}
inline bool CommonCode::is_horizontal_mirror() const {
return check_mirror(code_);
}
inline CommonCode CommonCode::to_vertical_mirror() const {
return unsafe_create(get_vertical_mirror(code_));
}
inline CommonCode CommonCode::to_horizontal_mirror() const {
return unsafe_create(get_horizontal_mirror(code_));
}
// ----------------------------------------------------------------------------------------- //
constexpr auto operator==(const CommonCode &lhs, const uint64_t rhs) { constexpr auto operator==(const CommonCode &lhs, const uint64_t rhs) {
return lhs.code_ == rhs; return lhs.code_ == rhs;
@ -119,6 +135,6 @@ constexpr auto operator<=>(const CommonCode &lhs, const CommonCode &rhs) {
return lhs.code_ <=> rhs.code_; return lhs.code_ <=> rhs.code_;
} }
// ------------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------------- //
} // namespace klotski::codec } // namespace klotski::codec

38
src/core/common_code/internal/mirror.cc

@ -1,23 +1,20 @@
#include <iostream>
#include <format> #include <format>
#include "common_code/common_code.h" #include "common_code/common_code.h"
using klotski::codec::CommonCode; using klotski::codec::CommonCode;
bool CommonCode::is_mirror(uint64_t common_code) { // TODO: performance optimization.
bool CommonCode::check_mirror(uint64_t common_code) {
int head = common_code >> 32; int head = common_code >> 32;
uint32_t ranges = range_reverse(common_code); uint32_t ranges = range_reverse(common_code);
// std::cout << "head = " << head << std::endl;
// std::cout << "ranges = " << std::format("{:08X}", ranges) << std::endl;
if (head % 4 != 1) { if (head % 4 != 1) {
return false; return false;
} }
std::array<bool, 6> state {}; // mark emtry/half-full std::array<bool, 5> state {}; // mark emtry/half-full
if (head == 1) { if (head == 1) {
state.at(0) = true; state.at(0) = true;
@ -38,16 +35,10 @@ bool CommonCode::is_mirror(uint64_t common_code) {
while (1 == 1) { while (1 == 1) {
if (working_line > 4) { if (working_line > 4) {
// std::cout << "reach end line" << std::endl;
break; break;
} }
// std::cout << std::endl;
// std::cout << "working_line: " << working_line << std::endl;
// std::cout << "state: " << std::format("{}", state) << std::endl;
if (!state.at(working_line)) { // empty line if (!state.at(working_line)) { // empty line
// std::cout << "empty working line" << std::endl;
/// simple single line /// simple single line
bool is_single_line = false; bool is_single_line = false;
@ -68,7 +59,6 @@ bool CommonCode::is_mirror(uint64_t common_code) {
} }
} }
if (is_single_line) { if (is_single_line) {
// std::cout << "simple single line" << std::endl;
++working_line; // next line ++working_line; // next line
continue; continue;
} }
@ -86,7 +76,6 @@ bool CommonCode::is_mirror(uint64_t common_code) {
} }
} }
if (is_half_double_line) { if (is_half_double_line) {
// std::cout << "half double line" << std::endl;
if (state.at(working_line + 1)) { if (state.at(working_line + 1)) {
working_line += 2; // next 2 lines working_line += 2; // next 2 lines
} else { } else {
@ -98,19 +87,15 @@ bool CommonCode::is_mirror(uint64_t common_code) {
/// full-double line /// full-double line
if ((ranges & 0b11111111) == 0b10101010) { if ((ranges & 0b11111111) == 0b10101010) {
// std::cout << "full double line" << std::endl;
ranges >>= 8; ranges >>= 8;
working_line += 2; working_line += 2;
continue; continue;
} }
// std::cout << "not mirror layout" << std::endl;
return false; return false;
} else { // half-full line } else { // half-full line
// std::cout << "half-full working line" << std::endl;
/// simple single line /// simple single line
bool is_simple_line = false; bool is_simple_line = false;
if ((ranges & 0b11) == 0b01) { if ((ranges & 0b11) == 0b01) {
@ -125,14 +110,12 @@ bool CommonCode::is_mirror(uint64_t common_code) {
} }
} }
if (is_simple_line) { if (is_simple_line) {
// std::cout << "simple single line" << std::endl;
++working_line; ++working_line;
continue; continue;
} }
/// half-double line /// half-double line
if ((ranges & 0b1111) == 0b1010) { if ((ranges & 0b1111) == 0b1010) {
// std::cout << "half double line" << std::endl;
ranges >>= 4; ranges >>= 4;
if (state.at(working_line + 1)) { if (state.at(working_line + 1)) {
working_line += 2; // next 2 lines working_line += 2; // next 2 lines
@ -143,12 +126,21 @@ bool CommonCode::is_mirror(uint64_t common_code) {
continue; continue;
} }
// std::cout << "not mirror layout" << std::endl;
return false; return false;
} }
} }
return true; return true;
} }
// TODO: temporarily use RawCode conversion.
uint64_t CommonCode::get_vertical_mirror(uint64_t common_code) {
auto raw_code = unsafe_create(common_code).to_raw_code();
return raw_code.to_vertical_mirror().to_common_code().unwrap();
}
// TODO: temporarily use RawCode conversion.
uint64_t CommonCode::get_horizontal_mirror(uint64_t common_code) {
auto raw_code = unsafe_create(common_code).to_raw_code();
return raw_code.to_horizontal_mirror().to_common_code().unwrap();
}

28
src/core/main.cc

@ -49,18 +49,36 @@ int main() {
// auto raw_code = CommonCode::unsafe_create(0x1A9BF0C00).to_raw_code(); // auto raw_code = CommonCode::unsafe_create(0x1A9BF0C00).to_raw_code();
// std::cout << raw_code.is_horizontal_mirror() << std::endl; // std::cout << raw_code.is_horizontal_mirror() << std::endl;
// for (auto common_code : AllCases::instance().fetch().codes()) { for (auto common_code : AllCases::instance().fetch().codes()) {
// auto raw_code = common_code.to_raw_code(); auto raw_code = common_code.to_raw_code();
//
// bool r1 = raw_code.is_horizontal_mirror(); // bool r1 = raw_code.is_horizontal_mirror();
// bool r2 = CommonCode::is_mirror(common_code.unwrap()); // bool r2 = common_code.is_horizontal_mirror();
// //
// if (r1 != r2) { // if (r1 != r2) {
// std::cout << "found invalid" << std::endl; // std::cout << "found invalid" << std::endl;
// std::cout << common_code << std::endl; // std::cout << common_code << std::endl;
// break; // break;
// } // }
// } //
// // if (raw_code.is_vertical_mirror()) {
// // std::cout << "found invalid" << std::endl;
// // break;
// // }
// auto rr = raw_code.to_vertical_mirror();
// auto cc = common_code.to_vertical_mirror();
auto rr = raw_code.to_horizontal_mirror();
auto cc = common_code.to_horizontal_mirror();
if (cc.to_raw_code() != rr) {
std::cout << "found invalid" << std::endl;
std::cout << common_code << std::endl;
break;
}
}
// GroupCases::from_info_t({169, 1, 7472}); // GroupCases::from_info_t({169, 1, 7472});

Loading…
Cancel
Save