12 struct locator final {
17 constexpr
auto to_tuple(
const locator<T>& a) {
18 return std::tie(a.x, a.y, a.z);
22 constexpr
bool operator==(
const locator<T>& a,
const locator<T>& b) {
23 return to_tuple(a) == to_tuple(b);
27 constexpr
bool operator!=(
const locator<T>& a,
const locator<T>& b) {
31 constexpr
size_t triangle(
size_t i) {
return (i * (i + 1)) / 2; }
33 static_assert(triangle(0) == 0,
"triangle");
34 static_assert(triangle(1) == 1,
"triangle");
35 static_assert(triangle(2) == 3,
"triangle");
36 static_assert(triangle(3) == 6,
"triangle");
37 static_assert(triangle(4) == 10,
"triangle");
38 static_assert(triangle(5) == 15,
"triangle");
40 constexpr
size_t tetrahedron(
size_t i) {
return (i * (i + 1) * (i + 2)) / 6; }
42 static_assert(tetrahedron(0) == 0,
"tetrahdedron");
43 static_assert(tetrahedron(1) == 1,
"tetrahdedron");
44 static_assert(tetrahedron(2) == 4,
"tetrahdedron");
45 static_assert(tetrahedron(3) == 10,
"tetrahdedron");
46 static_assert(tetrahedron(4) == 20,
"tetrahdedron");
47 static_assert(tetrahedron(5) == 35,
"tetrahdedron");
49 constexpr locator<size_t> to_locator(
size_t ind) {
51 for (
auto i = 1u;; ++i) {
52 auto tri = triangle(i);
61 for (
auto i = 1u;; ++i) {
71 return locator<size_t>{x, y, z};
74 static_assert(to_locator(0) == locator<size_t>{0, 0, 0},
"to_locator");
76 static_assert(to_locator(1) == locator<size_t>{1, 0, 0},
"to_locator");
77 static_assert(to_locator(2) == locator<size_t>{1, 1, 0},
"to_locator");
78 static_assert(to_locator(3) == locator<size_t>{1, 1, 1},
"to_locator");
80 static_assert(to_locator(4) == locator<size_t>{2, 0, 0},
"to_locator");
81 static_assert(to_locator(5) == locator<size_t>{2, 1, 0},
"to_locator");
82 static_assert(to_locator(6) == locator<size_t>{2, 1, 1},
"to_locator");
83 static_assert(to_locator(7) == locator<size_t>{2, 2, 0},
"to_locator");
84 static_assert(to_locator(8) == locator<size_t>{2, 2, 1},
"to_locator");
85 static_assert(to_locator(9) == locator<size_t>{2, 2, 2},
"to_locator");
87 static_assert(to_locator(10) == locator<size_t>{3, 0, 0},
"to_locator");
88 static_assert(to_locator(11) == locator<size_t>{3, 1, 0},
"to_locator");
89 static_assert(to_locator(12) == locator<size_t>{3, 1, 1},
"to_locator");
90 static_assert(to_locator(13) == locator<size_t>{3, 2, 0},
"to_locator");
91 static_assert(to_locator(14) == locator<size_t>{3, 2, 1},
"to_locator");
92 static_assert(to_locator(15) == locator<size_t>{3, 2, 2},
"to_locator");
93 static_assert(to_locator(16) == locator<size_t>{3, 3, 0},
"to_locator");
94 static_assert(to_locator(17) == locator<size_t>{3, 3, 1},
"to_locator");
95 static_assert(to_locator(18) == locator<size_t>{3, 3, 2},
"to_locator");
96 static_assert(to_locator(19) == locator<size_t>{3, 3, 3},
"to_locator");
98 constexpr
size_t abs(
int i) {
return std::max(i, -i); }
100 template <
typename T>
101 constexpr
void swap(T& a, T& b) {
107 constexpr locator<size_t> fold_locator(
const locator<int>& i) {
111 size_t plane = x + 1;
121 return locator<size_t>{x, y, z};
124 static_assert(fold_locator(locator<int>{0, 0, 0}) == locator<size_t>{0, 0, 0},
127 static_assert(fold_locator(locator<int>{1, 0, 0}) == locator<size_t>{1, 0, 0},
129 static_assert(fold_locator(locator<int>{-1, 0, 0}) == locator<size_t>{1, 0, 0},
131 static_assert(fold_locator(locator<int>{0, 1, 0}) == locator<size_t>{1, 0, 0},
133 static_assert(fold_locator(locator<int>{0, -1, 0}) == locator<size_t>{1, 0, 0},
135 static_assert(fold_locator(locator<int>{0, 0, 1}) == locator<size_t>{1, 0, 0},
137 static_assert(fold_locator(locator<int>{0, 0, -1}) == locator<size_t>{1, 0, 0},
140 static_assert(fold_locator(locator<int>{4, 0, 3}) == locator<size_t>{4, 3, 0},
142 static_assert(fold_locator(locator<int>{-4, 0, 3}) == locator<size_t>{4, 3, 0},
145 constexpr
size_t to_index(
const locator<size_t>& l) {
146 return tetrahedron(l.x) + triangle(l.y) + l.z;
149 static_assert(0 == to_index(locator<size_t>{0, 0, 0}),
"to_locator");
151 static_assert(1 == to_index(locator<size_t>{1, 0, 0}),
"to_locator");
152 static_assert(2 == to_index(locator<size_t>{1, 1, 0}),
"to_locator");
153 static_assert(3 == to_index(locator<size_t>{1, 1, 1}),
"to_locator");
155 static_assert(4 == to_index(locator<size_t>{2, 0, 0}),
"to_locator");
156 static_assert(5 == to_index(locator<size_t>{2, 1, 0}),
"to_locator");
157 static_assert(6 == to_index(locator<size_t>{2, 1, 1}),
"to_locator");
158 static_assert(7 == to_index(locator<size_t>{2, 2, 0}),
"to_locator");
159 static_assert(8 == to_index(locator<size_t>{2, 2, 1}),
"to_locator");
160 static_assert(9 == to_index(locator<size_t>{2, 2, 2}),
"to_locator");
162 static_assert(10 == to_index(locator<size_t>{3, 0, 0}),
"to_locator");
163 static_assert(11 == to_index(locator<size_t>{3, 1, 0}),
"to_locator");
164 static_assert(12 == to_index(locator<size_t>{3, 1, 1}),
"to_locator");
165 static_assert(13 == to_index(locator<size_t>{3, 2, 0}),
"to_locator");
166 static_assert(14 == to_index(locator<size_t>{3, 2, 1}),
"to_locator");
167 static_assert(15 == to_index(locator<size_t>{3, 2, 2}),
"to_locator");
168 static_assert(16 == to_index(locator<size_t>{3, 3, 0}),
"to_locator");
169 static_assert(17 == to_index(locator<size_t>{3, 3, 1}),
"to_locator");
170 static_assert(18 == to_index(locator<size_t>{3, 3, 2}),
"to_locator");
171 static_assert(19 == to_index(locator<size_t>{3, 3, 3}),
"to_locator");