diff --git a/all_cases/all_cases.h b/all_cases/all_cases.h new file mode 100644 index 0000000..78bd41e --- /dev/null +++ b/all_cases/all_cases.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include + +class AllCases { +public: +// std::vector all_cases; + + std::vector all_cases[16]; // 012 456 89A CDE + + std::vector basic_ranges; + void find_all_cases(); + +//protected: + static bool check_case(uint32_t head, uint32_t range); + void load_basic_ranges(); + +private: + void build_basic_ranges(int n1, int n2, int n3, int n4); + +}; diff --git a/all_cases/main.cc b/all_cases/main.cc index fee5f83..0d730dd 100644 --- a/all_cases/main.cc +++ b/all_cases/main.cc @@ -1,6 +1,7 @@ #include #include #include +#include "all_cases.h" inline uint32_t binary_count(uint32_t bin) { // get number of non-zero bits bin -= (bin >> 1) & 0x55555555; @@ -19,7 +20,7 @@ inline uint32_t binary_reverse(uint32_t bin) { // reverse binary every 2-bits return ((bin << 2) & 0xCCCCCCCC) | ((bin >> 2) & 0x33333333); } -bool check_case(uint32_t head, uint32_t range) { // check whether the case is valid +bool AllCases::check_case(uint32_t head, uint32_t range) { // check whether the case is valid uint32_t mask = 0b110011 << head; // fill 2x2 block for (int addr = 0; range; range >>= 2) { // traverse every 2-bits while (mask >> addr & 0b1) { @@ -47,10 +48,10 @@ bool check_case(uint32_t head, uint32_t range) { // check whether the case is va break; } } - return true; // case valid + return true; // valid case } -void build_basic_ranges(int n1, int n2, int n3, int n4, std::vector &ranges) { // build target ranges +void AllCases::build_basic_ranges(int n1, int n2, int n3, int n4) { // build target ranges int len, limit; constexpr uint32_t M_01 = 0b01 << 30; constexpr uint32_t M_10 = 0b10 << 30; @@ -67,7 +68,7 @@ void build_basic_ranges(int n1, int n2, int n3, int n4, std::vector &r for (int i = 0; i < len; ++i) { // generate range base on binary value range >>= 2; if ((bin >> i) & 0b1) { // non-zero bit - range |= M_01; + range |= M_01; // 01000... } } cache_1.emplace_back(range); // insert into first layer @@ -83,7 +84,7 @@ void build_basic_ranges(int n1, int n2, int n3, int n4, std::vector &r uint32_t range = 0; for (int i = 0; i < len; ++i) { // generate range base on binary value if ((bin >> i) & 0b1) { // non-zero bit - (range >>= 2) |= M_10; + (range >>= 2) |= M_10; // 10000... continue; } (range >>= 2) |= base & M_11; @@ -103,26 +104,26 @@ void build_basic_ranges(int n1, int n2, int n3, int n4, std::vector &r uint32_t range = 0; for (int i = 0; i < len; ++i) { // generate range base on binary value if ((bin >> i) & 0b1) { // non-zero bit - (range >>= 2) |= M_11; + (range >>= 2) |= M_11; // 11000... continue; } (range >>= 2) |= base & M_11; base <<= 2; } - ranges.emplace_back(range); // insert into release ranges + basic_ranges.emplace_back(range); // insert into release ranges } } } -void load_basic_ranges(std::vector &basic_ranges) { // load basic ranges +void AllCases::load_basic_ranges() { // load basic ranges basic_ranges.clear(); for (int n = 0; n <= 7; ++n) { // number of 1x2 and 2x1 block -> 0 ~ 7 for (int n_2x1 = 0; n_2x1 <= n; ++n_2x1) { // number of 2x1 block -> 0 ~ n for (int n_1x1 = 0; n_1x1 <= (14 - n * 2); ++n_1x1) { // number of 1x1 block -> 0 ~ (14 - 2n) int n_1x2 = n - n_2x1; int n_space = 16 - n * 2 - n_1x1; - // 0x0 -> 00 / 1x2 -> 01 / 2x1 -> 10 / 1x1 -> 11 - build_basic_ranges(n_space, n_1x2, n_2x1, n_1x1, basic_ranges); // build target ranges + /// 0x0 -> 00 | 1x2 -> 01 | 2x1 -> 10 | 1x1 -> 11 + build_basic_ranges(n_space, n_1x2, n_2x1, n_1x1); // build target ranges } } } @@ -132,18 +133,19 @@ void load_basic_ranges(std::vector &basic_ranges) { // load basic rang } } -void find_all_cases(std::vector &all_cases) { // find all valid cases - std::vector basic_ranges; - load_basic_ranges(basic_ranges); // load basic ranges - all_cases.clear(); +void AllCases::find_all_cases() { // find all valid cases +// all_cases.clear(); + load_basic_ranges(); // load basic ranges for (uint32_t head = 0; head < 16; ++head) { // address for 2x2 block - if ((head & 0b11) == 0b11) { // aka (head % 4 == 3) + all_cases[head].clear(); + if ((head & 0b11) == 0b11) { continue; } - uint64_t prefix = int64_t(head) << 32; +// uint64_t prefix = int64_t(head) << 32; for (uint32_t range : basic_ranges) { // combine 2x2 address and range if (check_case(head, range)) { - all_cases.emplace_back(prefix | binary_reverse(range)); // found valid case + all_cases[head].emplace_back(binary_reverse(range)); +// all_cases.emplace_back(prefix | binary_reverse(range)); // found valid case } } } @@ -151,15 +153,28 @@ void find_all_cases(std::vector &all_cases) { // find all valid cases int main() { - std::vector all_cases; - find_all_cases(all_cases); -// printf("size -> %ld\n", all_cases.size()); +// std::vector all_cases; +// find_all_cases(all_cases); +//// printf("size -> %ld\n", all_cases.size()); +// +// for (uint64_t temp : all_cases) { +// for (int i = 32; i >= 0; i -= 4) { +// printf("%lX", temp >> i & 0b1111); // show hex format +// } +// printf("\n"); +// } - for (uint64_t temp : all_cases) { - for (int i = 32; i >= 0; i -= 4) { - printf("%lX", temp >> i & 0b1111); // show hex format - } - printf("\n"); + auto a = AllCases(); + +// uint32_t range = binary_reverse(0xA9BF0C00); +// std::cout << a.check_case(3, range) << std::endl; + +// a.load_basic_ranges(); +// std::cout << a.basic_ranges.size() << std::endl; + + a.find_all_cases(); + for (const auto &all_case : a.all_cases) { + std::cout << all_case.size() << std::endl; } return 0;