|
@ -23,36 +23,31 @@ |
|
|
#define KLSK_ASSUME(expr) __builtin_assume(expr) |
|
|
#define KLSK_ASSUME(expr) __builtin_assume(expr) |
|
|
|
|
|
|
|
|
/// Force function declaration to be inline.
|
|
|
/// Force function declaration to be inline.
|
|
|
#define KLSK_INLINE __attribute__((always_inline)) |
|
|
#define KLSK_INLINE __attribute__ ((always_inline)) |
|
|
|
|
|
|
|
|
namespace klotski { |
|
|
namespace klotski { |
|
|
|
|
|
|
|
|
template <typename T> |
|
|
/// Calculate the sum of an array of integers.
|
|
|
concept Addable = requires(T a, T b) { a + b; }; |
|
|
template <typename T, size_t N> |
|
|
|
|
|
requires std::is_integral_v<T> |
|
|
template <Addable T, size_t N> |
|
|
|
|
|
consteval int array_sum(const std::array<T, N> &arr) { |
|
|
consteval int array_sum(const std::array<T, N> &arr) { |
|
|
return std::accumulate(arr.begin(), arr.end(), 0); |
|
|
return std::accumulate(arr.begin(), arr.end(), 0); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
template <Addable T, size_t N> |
|
|
/// Calculate offset list of integer array with sizes.
|
|
|
consteval std::array<T, N> to_offset(const std::array<T, N> &arr, T base) { |
|
|
template <typename T, size_t N> |
|
|
|
|
|
requires std::is_integral_v<T> |
|
|
static_assert(N > 0); |
|
|
consteval std::array<T, N> to_offset(const std::array<T, N> &arr) { |
|
|
|
|
|
|
|
|
std::array<T, N> offset; |
|
|
std::array<T, N> offset; |
|
|
|
|
|
static_assert(N > 0); |
|
|
T val = base; |
|
|
|
|
|
|
|
|
|
|
|
offset[0] = 0; |
|
|
offset[0] = 0; |
|
|
|
|
|
|
|
|
for (int i = 0; i < N - 1; ++i) { |
|
|
T val = 0; |
|
|
|
|
|
for (int i = 0; i < N - 1; ++i) { // TODO: using `std::views::iota`
|
|
|
val += arr[i]; |
|
|
val += arr[i]; |
|
|
offset[i + 1] = val; |
|
|
offset[i + 1] = val; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return offset; |
|
|
return offset; |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/// Flips the input u32 every two bits in low-high symmetry.
|
|
|
/// Flips the input u32 every two bits in low-high symmetry.
|
|
|