From 272caddc271e64f3ba08455dc01c2713d48b10ae Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Fri, 6 Jan 2023 15:29:37 +0800 Subject: [PATCH] fix: enhance common code check --- klotski/common.cc | 33 --------------------------------- klotski/common.h | 1 - klotski/common_code.cc | 24 ++++++++++++++++++++++-- klotski/main.cc | 31 ++++++++++++++++--------------- 4 files changed, 38 insertions(+), 51 deletions(-) diff --git a/klotski/common.cc b/klotski/common.cc index 8118f23..13bc5a6 100644 --- a/klotski/common.cc +++ b/klotski/common.cc @@ -37,36 +37,3 @@ bool Common::check_case(uint32_t head, uint32_t range) { // whether the head and } return true; // valid case } - -bool Common::check_case_safe(uint32_t head, uint32_t range) { // whether the case is valid - uint32_t space_num = 0; - uint32_t mask = 0b110011 << head; // fill 2x2 block - for (int addr = 0; range; range >>= 2) { // traverse every 2-bits - while (mask >> addr & 0b1) { - ++addr; // search next not filled block - } - switch (range & 0b11) { - case 0b00: // space block - ++space_num; - case 0b11: // 1x1 block - if (addr > 19) { // invalid address - return false; - } - mask |= 0b1 << addr; // fill 1x1 block - break; - case 0b10: // 2x1 block - if (addr > 15 || mask >> (addr + 4) & 0b1) { // invalid address - return false; - } - mask |= 0b10001 << addr; // fill 2x1 block - break; - case 0b01: // 1x2 block - if (addr > 18 || (addr & 0b11) == 0b11 || mask >> (addr + 1) & 0b1) { // invalid address - return false; - } - mask |= 0b11 << addr; // fill 1x2 block - break; - } - } - return space_num >= 2; // at least 2 space -} diff --git a/klotski/common.h b/klotski/common.h index 505bef1..8c80a6c 100644 --- a/klotski/common.h +++ b/klotski/common.h @@ -6,5 +6,4 @@ class Common { public: static uint32_t range_reverse(uint32_t bin); static bool check_case(uint32_t head, uint32_t range); - static bool check_case_safe(uint32_t head, uint32_t range); }; diff --git a/klotski/common_code.cc b/klotski/common_code.cc index e4e403d..75b9fbd 100644 --- a/klotski/common_code.cc +++ b/klotski/common_code.cc @@ -3,9 +3,29 @@ bool CommonCode::check(uint64_t common_code) { uint32_t head = common_code >> 32; - auto range = (uint32_t)common_code; if (head >= 16 || (head & 0b11) == 0b11) { // check 2x2 block address return false; // invalid common code } - return Common::check_case_safe(head, Common::range_reverse(range)); // check by head and range + + uint32_t fill_num = 0, space_num = 0; + auto range = Common::range_reverse((uint32_t)common_code); // get common code range + for (int i = 0; i < 32; i += 2) { // traverse range + switch ((range >> i) & 0b11) { + case 0b00: // space block + ++space_num; + case 0b11: // 1x1 block + ++fill_num; + break; + case 0b01: // 1x2 block + case 0b10: // 2x1 block + fill_num += 2; + } + if (fill_num >= 16) { // all block filled + break; + } + } + if (space_num < 2) { + return false; // at least 2 space + } + return Common::check_case(head, range); // check by head and range } diff --git a/klotski/main.cc b/klotski/main.cc index 4b1f2dd..408e1a0 100644 --- a/klotski/main.cc +++ b/klotski/main.cc @@ -46,28 +46,29 @@ int main() { // } // uint32_t sum = 0; -// for (uint32_t head = 0; head < 1; ++head) { -// auto prefix = (uint64_t)head << 32; -// for (uint64_t range = 0; range < 0x100000000; ++range) { -// uint64_t code = prefix | range; -// if (CommonCode::check(code)) { -// printf("%09lX\n", code); + for (uint32_t head = 0; head < 16; ++head) { + auto prefix = (uint64_t)head << 32; + for (uint64_t range = 0; range < 0x100000000; ++range) { + uint64_t code = prefix | range; + if (CommonCode::check(code)) { + printf("%09lX\n", code); // ++sum; -// } + } // if (range % 0x1000000 == 0) { // std::cout << range / 0x1000000 << std::endl; // } -// } -// } + } + } // std::cout << "sum: " << sum << std::endl; - uint64_t error_code = 0x02EFFF7C0; +// uint64_t error_code = 0x02EFFF7C0; +// uint64_t error_code = 0x07B4EFC00; - if (CommonCode::check(error_code)) { - std::cout << "true" << std::endl; - } else { - std::cout << "false" << std::endl; - } +// if (CommonCode::check(error_code)) { +// std::cout << "true" << std::endl; +// } else { +// std::cout << "false" << std::endl; +// } return 0; }