diff --git a/src/klotski/all_cases/all_cases.h b/src/klotski/all_cases/all_cases.h index 4eca3c1..6e83cc3 100644 --- a/src/klotski/all_cases/all_cases.h +++ b/src/klotski/all_cases/all_cases.h @@ -1,5 +1,29 @@ #pragma once +/// AllCases can generate all valid CommonCodes, a total of 29334498 kinds. +/// For the generated BasicRanges, use different `2x2` block positions to +/// check respectively. On the `5x4` chessboard, it has 12 possible positions, +/// and the numbers are distributed in 0 ~ 15, witch called `head`. For the +/// convenience of calculation, here use an array of length 16 for storage, +/// of course, the position of 3/7/11/15 will be empty. + +/// 00 01 02 03 +/// 04 05 06 07 00 01 02 +/// 08 09 10 11 04 05 06 <- head of 2x2 block +/// 12 13 14 15 08 09 10 +/// 16 17 18 19 12 13 14 + +/// After checking, each head has a different valid `range`, and they are +/// stored in different arrays to save memory (otherwise the 64-bits length +/// must be consumed), and all CommonCodes can be exported by using the +/// following code, which is also integrated in FFI. + +/// for (uint64_t head = 0; head < 16; ++head) { +/// for (const auto &range : AllCases::fetch()[head]) { +/// printf("%09lX\n", head << 32 | range); +/// } +/// } + #include #include #include diff --git a/src/klotski/all_cases/basic_ranges.h b/src/klotski/all_cases/basic_ranges.h index fc097e8..3b06d6c 100644 --- a/src/klotski/all_cases/basic_ranges.h +++ b/src/klotski/all_cases/basic_ranges.h @@ -1,5 +1,31 @@ #pragma once +/// Based on the requirements of valid klotski, the `2x2` block that must exist +/// and only one, witch will occupy 4 empty slots, and the remaining 16 slots +/// will be allocated to space, `1x2`, `2x1` and `1x1`. Then, according to the +/// rules of CommonCode, they are coded as `00` `01` `10` `11` respectively, and +/// the remaining positions are filled with `0` and stored as 32-bits variables. + +/// As we all know, a space or `1x1` block will occupy 1 slot, `1x2` or `2x1` +/// block will occupy 2 slots, and together they fill 16 positions, so all +/// possible combinations can be calculated, this number is 204. Each combination +/// can produce different permutations. After verification, there are a total of +/// 7311921 possible permutations. The goal of BasicRanges is to find these +/// permutations, sort them and store them in a `uint32_t` array. + +/// In terms of algorithms, there are two options: the first is to generate +/// out-of-order data and then quickly arrange them; the second is to generate +/// ordered data for 204 combinations, and then merge and sort them. After testing, +/// the former is faster in generation (consuming T time), but it will consume +/// more time in sorting (about 7T), and the latter will cost about 2T in +/// generation due to the loss of the tree structure queue. But it can save more +/// time in sorting, which is about 2T, so the second solution will get the result +/// faster. + +/// Finally, due to the performance considerations of AllCases, the resulting data +/// will be flipped every two bits, which will not consume too much time (less than +/// 10% of T), but can almost double the speed of the subsequent `check_range`. + #include #include #include