From 1bb7b6f10ca3c609daa82ad133a2ccb36b4f176b Mon Sep 17 00:00:00 2001 From: dnomd343 Date: Tue, 30 Aug 2022 18:37:42 +0800 Subject: [PATCH] update: test raw code and compact code --- CMakeLists.txt | 2 +- case.cpp => case.cc | 153 +++++++++++++--------------------- case.h | 9 ++ common.cc | 31 +++++++ common.h | 10 +++ klotski | Bin 0 -> 22584 bytes klotski.cc | 55 +++++++++++++ klotski.h | 73 +++++++++++++++++ main.cc | 84 +++++++++++++++++++ main.cpp | 195 -------------------------------------------- 10 files changed, 319 insertions(+), 293 deletions(-) rename case.cpp => case.cc (76%) create mode 100644 case.h create mode 100644 common.cc create mode 100644 common.h create mode 100755 klotski create mode 100644 klotski.cc create mode 100644 klotski.h create mode 100644 main.cc delete mode 100644 main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d25c18..cdafd10 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,4 +3,4 @@ project(klotski) set(CMAKE_CXX_STANDARD 14) -add_executable(klotski main.cpp) +add_executable(klotski main.cc case.cc common.cc klotski.cc) diff --git a/case.cpp b/case.cc similarity index 76% rename from case.cpp rename to case.cc index e685da8..83502e1 100644 --- a/case.cpp +++ b/case.cc @@ -1,66 +1,43 @@ -#include -#include +#include "case.h" +#include "common.h" #include -typedef __uint32_t uint32_t; -typedef __uint64_t uint64_t; +bool check_case(int head, uint32_t range); +void build_base_range(std::vector &base_range); +void gen_range(std::vector &release, int n1, int n2, int n3, int n4); -inline int binary_num(uint32_t binary, int length) { // get number of non-zero bit - int num = 0; - for (int i = 0; i < length; ++i) { - num += int((binary >> i) & 0x1); - } - return num; -} - -inline void binary_reverse(uint32_t &range) { // reverse binary every 2 bits - range = ((range << 16) & 0xFFFF0000) | ((range >> 16) & 0x0000FFFF); - range = ((range << 8) & 0xFF00FF00) | ((range >> 8) & 0x00FF00FF); - range = ((range << 4) & 0xF0F0F0F0) | ((range >> 4) & 0x0F0F0F0F); - range = ((range << 2) & 0xCCCCCCCC) | ((range >> 2) & 0x33333333); -} - -inline void binary_to_str(uint64_t binary, char *string) { - for (int i = 0; i < 9; ++i, ++string) { // only read low 9 * 4 bits - *string = int8_t(binary >> (8 - i) * 4 & 0xF); - if (*string < 10) { - *string += 48; // 0 -> 48 - } else { - *string += 55; // A -> 65 +void find_all_case(std::vector *all_case) { + all_case->clear(); + std::vector base_range; + build_base_range(base_range); + for (int head = 0; head < 16; ++head) { // address for 2x2 block + if (head % 4 != 3) { + uint64_t prefix = int64_t(head) << 32; + for (auto range : base_range) { // combine 2x2 address and range + if (check_case(head, range)) { + binary_reverse(range); + all_case->emplace_back(prefix | range); + } + } } } - string[9] = 0x0; // string ending } -bool check_case(int head, uint32_t range) { // whether case is valid - uint32_t status = 0x33 << head; - for (int addr = 0; range; range >>= 2) { - while (status >> addr & 0x1) { - ++addr; - } - switch (range & 0x3) { - case 0x0: // space - case 0x3: // 1x1 - if (addr > 19) { - return false; - } - status |= 0x1 << addr; - break; - case 0x1: // 1x2 - if (addr % 4 == 3 || addr > 18 || status >> (addr + 1) & 0x1) { - return false; - } - status |= 0x3 << addr; - break; - case 0x2: // 2x1 - if (addr > 15 || status >> (addr + 4) & 0x1) { - return false; - } - status |= 0x11 << addr; - break; +void build_base_range(std::vector &base_range) { + for (int n = 0; n <= 7; ++n) { // number of 1x2 and 2x1 block -> 0 ~ (20 - 4 - 2) / 2 + for (int n_2x1 = 0; n_2x1 <= n; ++n_2x1) { // number of 1x2 block + for (int n_1x1 = 0; n_1x1 <= (14 - n * 2); ++n_1x1) { // number of 1x1 block + gen_range(base_range, (16 - n * 2 - n_1x1), (n - n_2x1), n_2x1, n_1x1); + } } } - return true; + for (auto &bin : base_range) { + binary_reverse(bin); + } + std::sort(base_range.begin(), base_range.end()); + for (auto &bin : base_range) { + binary_reverse(bin); + } } void gen_range(std::vector &release, int n1, int n2, int n3, int n4) { @@ -114,51 +91,33 @@ void gen_range(std::vector &release, int n1, int n2, int n3, int n4) { } } -void build_base_range(std::vector &base_range) { - for (int n = 0; n <= 7; ++n) { // number of 1x2 and 2x1 block -> 0 ~ (20 - 4 - 2) / 2 - for (int n_2x1 = 0; n_2x1 <= n; ++n_2x1) { // number of 1x2 block - for (int n_1x1 = 0; n_1x1 <= (14 - n * 2); ++n_1x1) { // number of 1x1 block - gen_range(base_range, (16 - n * 2 - n_1x1), (n - n_2x1), n_2x1, n_1x1); - } +bool check_case(int head, uint32_t range) { // whether case is valid + uint32_t status = 0x33 << head; + for (int addr = 0; range; range >>= 2) { + while (status >> addr & 0x1) { + ++addr; } - } - for (auto &bin : base_range) { - binary_reverse(bin); - } - std::sort(base_range.begin(), base_range.end()); - for (auto &bin : base_range) { - binary_reverse(bin); - } -} - -void find_all_case(std::vector *all_case) { - all_case->clear(); - std::vector base_range; - build_base_range(base_range); - for (int head = 0; head < 16; ++head) { // address for 2x2 block - if (head % 4 != 3) { - uint64_t prefix = int64_t(head) << 32; - for (auto range : base_range) { // combine 2x2 address and range - if (check_case(head, range)) { - binary_reverse(range); - all_case->emplace_back(prefix | range); + switch (range & 0x3) { + case 0x0: // space + case 0x3: // 1x1 + if (addr > 19) { + return false; } - } + status |= 0x1 << addr; + break; + case 0x1: // 1x2 + if (addr % 4 == 3 || addr > 18 || status >> (addr + 1) & 0x1) { + return false; + } + status |= 0x3 << addr; + break; + case 0x2: // 2x1 + if (addr > 15 || status >> (addr + 4) & 0x1) { + return false; + } + status |= 0x11 << addr; + break; } } -} - -int main() { - std::vector all_case; - find_all_case(&all_case); - -// printf("count -> %lu\n", all_case.size()); - - for (auto code : all_case) { - char str[10]; - binary_to_str(code, str); - printf("%s\n", str); - } - - return 0; + return true; } diff --git a/case.h b/case.h new file mode 100644 index 0000000..8c65854 --- /dev/null +++ b/case.h @@ -0,0 +1,9 @@ +#ifndef _CASE_H_ +#define _CASE_H_ + +#include +#include + +void find_all_case(std::vector *all_case); + +#endif diff --git a/common.cc b/common.cc new file mode 100644 index 0000000..a009e0c --- /dev/null +++ b/common.cc @@ -0,0 +1,31 @@ +#include "common.h" + +//inline int binary_num(uint32_t binary, int length) { // get number of non-zero bit +int binary_num(uint32_t binary, int length) { // get number of non-zero bit + int num = 0; + for (int i = 0; i < length; ++i) { + num += int((binary >> i) & 0x1); + } + return num; +} + +//inline void binary_reverse(uint32_t &range) { // reverse binary every 2 bits +void binary_reverse(uint32_t &range) { // reverse binary every 2 bits + range = ((range << 16) & 0xFFFF0000) | ((range >> 16) & 0x0000FFFF); + range = ((range << 8) & 0xFF00FF00) | ((range >> 8) & 0x00FF00FF); + range = ((range << 4) & 0xF0F0F0F0) | ((range >> 4) & 0x0F0F0F0F); + range = ((range << 2) & 0xCCCCCCCC) | ((range >> 2) & 0x33333333); +} + +//inline void binary_to_str(uint64_t binary, char *string) { +void binary_to_str(uint64_t binary, char *string) { + for (int i = 0; i < 9; ++i, ++string) { // only read low 9 * 4 bits + *string = int8_t(binary >> (8 - i) * 4 & 0xF); + if (*string < 10) { + *string += 48; // 0 -> 48 + } else { + *string += 55; // A -> 65 + } + } + string[9] = 0x0; // string ending +} diff --git a/common.h b/common.h new file mode 100644 index 0000000..0b2ad51 --- /dev/null +++ b/common.h @@ -0,0 +1,10 @@ +#ifndef _COMMON_H_ +#define _COMMON_H_ + +#include + +void binary_reverse(uint32_t &range); +int binary_num(uint32_t binary, int length); +void binary_to_str(uint64_t binary, char *string); + +#endif diff --git a/klotski b/klotski new file mode 100755 index 0000000000000000000000000000000000000000..0a5662895ec099a56f7763360d38e5d9ed1fc64f GIT binary patch literal 22584 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 jgTwfIAYi}&5%_qeXjjlqL?#>mswD=+>= 3) { + switch (code & 0x7) { + case B_space: + range <<= 2; + break; + case B_1x2: + (range <<= 2) |= 0x1; + break; + case B_2x1: + (range <<= 2) |= 0x2; + break; + case B_1x1: + (range <<= 2) |= 0x3; + break; + case B_2x2: + ret |= uint64_t(addr) << 32; + default: + continue; + } + ++block_num; + } + return ret | range << (16 - block_num) * 2; +} + +uint64_t extract_code(uint64_t code) { + uint64_t ret = C_2x2 << (code >> 32) * 3; + auto range = uint32_t(code); + binary_reverse(range); + for (int addr = 0; range; range >>= 2) { + while (0x7 & ret >> addr) { + addr += 3; + } + switch (range & 0x3) { + case 0x1: + ret |= C_1x2 << addr; + break; + case 0x2: + ret |= C_2x1 << addr; + break; + case 0x3: + ret |= C_1x1 << addr; + break; + case 0x0: + addr += 3; + } + } + return ret; +} diff --git a/klotski.h b/klotski.h new file mode 100644 index 0000000..19c1230 --- /dev/null +++ b/klotski.h @@ -0,0 +1,73 @@ +#ifndef _KLOTSKI_H_ +#define _KLOTSKI_H_ + +#include + +#define B_space 0x0 +#define B_fill 0x7 +#define B_1x2 0x1 +#define B_2x1 0x2 +#define B_1x1 0x3 +#define B_2x2 0x4 + +#define C_1x1 int64_t(0x3) +#define C_1x2 int64_t(0x39) +#define C_2x1 int64_t(0x7002) +#define C_2x2 int64_t(0x3F03C) + +#define F_1x1 int64_t(0x7) +#define F_1x2 int64_t(0x3F) +#define F_2x1 int64_t(0x7007) +#define F_2x2 int64_t(0x3F03F) + +uint64_t compact_code(uint64_t code); +uint64_t extract_code(uint64_t code); + +#endif + +/* + + uint64_t -> 0000 + [xxx] * 20 + + 2x2 2x1 1x2 1x1 + # # # # # # + # # # + + 00 01 02 03 + 04 05 06 07 + 08 09 10 11 + 12 13 14 15 + 16 17 18 19 + + x1 (%4) => 0 1 2 3 + x3 (%4) => 0 3 2 1 + +*/ + +/* +====================================================== + + 1x1 -> 011 000 000 000 -> 0000 0000 0011 -> 0x3 + + 1x2 -> 001 111 000 000 -> 0000 0011 1001 -> 0x39 + + 2x1 -> 010 000 000 000 -> 0000 0000 0010 -> 0x7002 + 111 000 000 000 -> 0000 0000 0111 + + 2x2 -> 100 111 000 000 -> 0000 0011 1100 -> 0x3F03C + 111 111 000 000 -> 0000 0011 1111 + +====================================================== + + 1x1 -> 111 000 000 000 -> 0000 0000 0111 -> 0x7 + + 1x2 -> 111 111 000 000 -> 0000 0011 1111 -> 0x3F + + 2x1 -> 111 000 000 000 -> 0000 0000 0111 -> 0x7007 + 111 000 000 000 -> 0000 0000 0111 + + 2x2 -> 111 111 000 000 -> 0000 0011 1111 -> 0x3F03F + 111 111 000 000 -> 0000 0011 1111 + +====================================================== +*/ diff --git a/main.cc b/main.cc new file mode 100644 index 0000000..93eaa20 --- /dev/null +++ b/main.cc @@ -0,0 +1,84 @@ +#include "case.h" +#include "klotski.h" +#include +#include +#include + +void graph_output(uint64_t code) { + for (int i = 0; i < 20; ++i) { + switch (code & 0x7) { + case B_1x1: + printf("# "); + break; + case B_1x2: + printf("& "); + break; + case B_2x1: + printf("$ "); + break; + case B_2x2: + printf("@ "); + break; + case B_fill: + printf("* "); + break; + case B_space: + printf(". "); + break; + default: + printf("? "); + } + if ((i & 0x3) == 0x3) { + printf("\n"); + } + code >>= 3; + } +} + +int main() { + printf("Klotski engine\n"); + +// printf("%lx\n", compact_code(0x0E58FC85FFEBC4DB)); +// printf("%lx\n", compact_code(0x0603EDF5CAFFF5E2)); + +// graph_output(extract_code(0x4FEA13400)); +// printf("\n"); +// graph_output(extract_code(0x1A9BF0C00)); +// printf("\n"); + + std::vector all_case; + find_all_case(&all_case); + printf("count -> %lu\n", all_case.size()); + + for (auto code : all_case) { + if (code != compact_code(extract_code(code))) { + printf("error -> %lx\n", code); + } + } + + return 0; + + // 0x4FEA13400 + // # # # @ | 011 011 011 010 => 0100 1101 1011 -> 4DB + // * * & @ | 100 111 010 111 => 1110 1011 1100 -> EBC + // * * & $ | 111 111 111 010 => 0101 1111 1111 -> 5FF + // . + + $ | 000 001 111 111 => 1111 1100 1000 -> FC8 + // . # ~ ~ | 000 011 001 111 => 1110 0101 1000 -> E58 + // 0x0E58FC85FFEBC4DB + + graph_output(0x0E58FC85FFEBC4DB); + printf("\n"); + + // 0x1A9BF0C00 + // @ * * @ | 010 100 111 010 => 0101 1110 0010 -> 5E2 + // @ * * @ | 111 111 111 111 => 1111 1111 1111 -> FFF + // $ ~ ~ $ | 010 001 111 010 => 0101 1100 1010 -> 5CA + // $ # # $ | 111 011 011 111 => 1110 1101 1111 -> EDF + // # . . # | 011 000 000 011 => 0110 0000 0011 -> 603 + // 0x0603EDF5CAFFF5E2 + + graph_output(0x0603EDF5CAFFF5E2); + printf("\n"); + + return 0; +} diff --git a/main.cpp b/main.cpp deleted file mode 100644 index a1e349d..0000000 --- a/main.cpp +++ /dev/null @@ -1,195 +0,0 @@ -#include -#include - -#define B_space 0x0 -#define B_fill 0x7 -#define B_1x2 0x1 -#define B_2x1 0x2 -#define B_1x1 0x3 -#define B_2x2 0x4 - -#define C_1x1 int64_t(0x3) -#define C_1x2 int64_t(0x39) -#define C_2x1 int64_t(0x7002) -#define C_2x2 int64_t(0x3F03C) - -#define F_1x1 int64_t(0x7) -#define F_1x2 int64_t(0x3F) -#define F_2x1 int64_t(0x7007) -#define F_2x2 int64_t(0x3F03F) - -/* - - uint64_t -> 0000 + [xxx] * 20 - - 2x2 2x1 1x2 1x1 - # # # # # # - # # # - - 00 01 02 03 - 04 05 06 07 - 08 09 10 11 - 12 13 14 15 - 16 17 18 19 - - x1 (%4) => 0 1 2 3 - x3 (%4) => 0 3 2 1 - -*/ - -/* -====================================================== - - 1x1 -> 011 000 000 000 -> 0000 0000 0011 -> 0x3 - - 1x2 -> 001 111 000 000 -> 0000 0011 1001 -> 0x39 - - 2x1 -> 010 000 000 000 -> 0000 0000 0010 -> 0x7002 - 111 000 000 000 -> 0000 0000 0111 - - 2x2 -> 100 111 000 000 -> 0000 0011 1100 -> 0x3F03C - 111 111 000 000 -> 0000 0011 1111 - -====================================================== - - 1x1 -> 111 000 000 000 -> 0000 0000 0111 -> 0x7 - - 1x2 -> 111 111 000 000 -> 0000 0011 1111 -> 0x3F - - 2x1 -> 111 000 000 000 -> 0000 0000 0111 -> 0x7007 - 111 000 000 000 -> 0000 0000 0111 - - 2x2 -> 111 111 000 000 -> 0000 0011 1111 -> 0x3F03F - 111 111 000 000 -> 0000 0011 1111 - -====================================================== -*/ - -void graph_output(uint64_t code) { - for (int i = 0; i < 20; ++i) { - switch (code & 0x7) { - case B_1x1: - printf("# "); - break; - case B_1x2: - printf("& "); - break; - case B_2x1: - printf("$ "); - break; - case B_2x2: - printf("@ "); - break; - case B_fill: - printf("* "); - break; - case B_space: - printf(". "); - break; - default: - printf("? "); - } - if ((i & 0x3) == 0x3) { - printf("\n"); - } - code >>= 3; - } -} - -uint64_t compact_code(uint64_t code) { - int block_num = 0; - uint64_t ret = 0; - uint32_t range = 0; - for (int addr = 0; code; ++addr, code >>= 3) { - switch (code & 0x7) { - case B_space: - range <<= 2; - break; - case B_1x2: - (range <<= 2) |= 0x1; - break; - case B_2x1: - (range <<= 2) |= 0x2; - break; - case B_1x1: - (range <<= 2) |= 0x3; - break; - case B_2x2: - ret |= uint64_t(addr) << 32; - default: - continue; - } - ++block_num; - } - return ret | range << (16 - block_num) * 2; -} - -inline void binary_reverse(uint32_t &range) { // reverse binary every 2 bits - range = ((range << 16) & 0xFFFF0000) | ((range >> 16) & 0x0000FFFF); - range = ((range << 8) & 0xFF00FF00) | ((range >> 8) & 0x00FF00FF); - range = ((range << 4) & 0xF0F0F0F0) | ((range >> 4) & 0x0F0F0F0F); - range = ((range << 2) & 0xCCCCCCCC) | ((range >> 2) & 0x33333333); -} - -uint64_t extract_code(uint64_t code) { - uint64_t ret = C_2x2 << (code >> 32) * 3; - auto range = uint32_t(code); - binary_reverse(range); - for (int addr = 0; range; range >>= 2) { - while (0x7 & ret >> addr) { - addr += 3; - } - switch (range & 0x3) { - case 0x1: - ret |= C_1x2 << addr; - break; - case 0x2: - ret |= C_2x1 << addr; - break; - case 0x3: - ret |= C_1x1 << addr; - break; - case 0x0: - addr += 3; - } - } - return ret; -} - -int main() { - printf("Klotski engine\n"); - -// printf("%lx\n", compact_code(0x0E58FC85FFEBC4DB)); -// printf("%lx\n", compact_code(0x0603EDF5CAFFF5E2)); - - graph_output(extract_code(0x4FEA13400)); - printf("\n"); - graph_output(extract_code(0x1A9BF0C00)); - printf("\n"); - - return 0; - - // 0x4FEA13400 - // # # # @ | 011 011 011 010 => 0100 1101 1011 -> 4DB - // * * & @ | 100 111 010 111 => 1110 1011 1100 -> EBC - // * * & $ | 111 111 111 010 => 0101 1111 1111 -> 5FF - // . + + $ | 000 001 111 111 => 1111 1100 1000 -> FC8 - // . # ~ ~ | 000 011 001 111 => 1110 0101 1000 -> E58 - // 0x0E58FC85FFEBC4DB - - graph_output(0x0E58FC85FFEBC4DB); - printf("\n"); - - // 0x1A9BF0C00 - // @ * * @ | 010 100 111 010 => 0101 1110 0010 -> 5E2 - // @ * * @ | 111 111 111 111 => 1111 1111 1111 -> FFF - // $ ~ ~ $ | 010 001 111 010 => 0101 1100 1010 -> 5CA - // $ # # $ | 111 011 011 111 => 1110 1101 1111 -> EDF - // # . . # | 011 000 000 011 => 0110 0000 0011 -> 603 - // 0x0603EDF5CAFFF5E2 - - graph_output(0x0603EDF5CAFFF5E2); - printf("\n"); - - return 0; -}