8 #ifndef INCLUDE_MOLASSEMBLER_TEMPLE_PERMUTATIONS_H
9 #define INCLUDE_MOLASSEMBLER_TEMPLE_PERMUTATIONS_H
15 namespace Molassembler {
26 template<
class Container>
28 const std::size_t size = container.size();
30 std::size_t index = 0;
31 std::size_t position = 2;
32 std::size_t factor = 1;
34 for(std::size_t p = size - 2; p != std::numeric_limits<std::size_t>::max(); --p) {
35 std::size_t largerSuccessors = 0;
37 for(std::size_t q = p + 1; q < size; ++q) {
38 if(container[q] < container[p]) {
43 index += (largerSuccessors * factor);
55 template<
typename Container>
61 auto intermediate = std::move(data.at(b));
62 data.at(b) = std::move(data.at(a));
63 data.at(a) = std::move(intermediate);
70 template<
typename Container>
73 const std::size_t indexFrom,
74 const std::size_t indexTo
76 std::size_t a = indexFrom;
77 std::size_t b = indexTo;
78 while(a != b && a != --b) {
91 template<
typename Container>
94 const std::size_t
first,
95 const std::size_t last
97 std::size_t size = data.size();
103 throw "Call parameters to inPlaceNextPermutation make no sense!";
106 std::size_t i = last - 1;
115 && data.at(--i) < data.at(j)
121 && !(data.at(i) < data.at(--k))
137 template<
typename Container>
150 template<
typename Container>
153 const std::size_t
first,
154 const std::size_t last
156 unsigned size = data.size();
162 throw "Call parameters to inPlaceNextPermutation make no sense!";
165 std::size_t i = last - 1;
174 && data.at(j) < data.at(--i)
180 && !(data.at(--k) < data.at(i))
196 template<
typename Container>
203 template<
class Container>
206 std::begin(container),
212 template<
class Container>
215 std::begin(container),
235 template<
class Container>
240 assert(toPermute.size() == limits.size());
241 const unsigned cols = toPermute.size();
245 for(
unsigned i = 0; i < cols; ++i) {
246 if(toPermute[i] != limits[i]) {
257 for(
int i = cols - 1; i >= 0; --i) {
258 if(toPermute[i] == limits[i]) {
284 template<
typename Container>
286 using T = std::decay_t<decltype(std::declval<Container>().at(0))>;
288 std::is_convertible<T, unsigned>::value,
289 "Permutation container value type must be convertible to an integral type"
296 for(
unsigned i = 0; i < N; ++i) {
307 factorials.at(0) = 1;
308 for(
unsigned k = 1; k < N; ++k) {
309 factorials.at(k) = factorials.at(k - 1) * k;
312 for(
unsigned k = 0; k < N; ++k) {
313 const unsigned fac = factorials.at(N - 1 - k);
314 sigma.at(k) = i / fac;
318 for(
int k = static_cast<int>(N) - 1; k > 0; --k) {
319 for(
int j = k - 1; j >= 0; --j) {
328 template<
typename OtherContainer>
334 [&](
const auto i,
const auto j) {
335 return unordered.at(i) < unordered.at(j);
341 constexpr
bool next() {
345 constexpr
bool prev() {
349 constexpr std::size_t index()
const {
354 auto inverted = sigma;
355 const unsigned size = inverted.size();
356 for(
unsigned i = 0; i < size; ++i) {
357 inverted.at(sigma.at(i)) = i;
362 constexpr
auto at(
const std::size_t i)
const -> decltype(
auto) {
366 constexpr
auto operator() (
const std::size_t i)
const -> decltype(
auto) {
370 template<
typename OtherContainer>
371 constexpr OtherContainer apply(
const OtherContainer& other)
const {
372 const unsigned size = other.size();
373 OtherContainer result(size);
374 for(std::size_t i = 0; i < size; ++i) {
375 result.at(i) = other.at(sigma.at(i));
393 template<
typename Container>
void sort(Container &container)
Calls std::sort on a container.
Definition: Functional.h:261
constexpr Permutation(unsigned N)
Construct the identity permutation of size N.
Definition: Permutations.h:295
bool next_permutation(Container &container)
Calls std::next_permutation.
Definition: Permutations.h:204
Constexpr-compatible container-abstracted permutation.
Definition: Permutations.h:285
bool nextCombinationPermutation(Container &toPermute, const Container &limits)
For when you have to implement variable-depth for loops, each with different limits.
Definition: Permutations.h:236
auto at(Container &&container)
Make functor calling at on arguments.
Definition: Functor.h:58
constexpr Permutation(const unsigned N, unsigned i)
Construct the i-th permutation of size N.
Definition: Permutations.h:305
constexpr Permutation compose(const Permutation &other) const
Compose two permutations.
Definition: Permutations.h:385
constexpr std::size_t permutationIndex(const Container &container)
Calculate the index of permutation of elements in a container.
Definition: Permutations.h:27
constexpr void inPlaceReverse(Container &data, const std::size_t indexFrom, const std::size_t indexTo)
Index-based in-place reversal of elements in an array-like container.
Definition: Permutations.h:71
unsigned size(Shape shape)
Fetch the number of vertices of a shape.
Container sigma
The permutation in 'one-line' representation.
Definition: Permutations.h:390
static constexpr Permutation ordering(const OtherContainer &unordered)
Discover on ordering permutation of an unordered container.
Definition: Permutations.h:329
bool prev_permutation(Container &container)
Calls std::prev_permutation.
Definition: Permutations.h:213
constexpr Permutation(Container p)
Construct a permutation from data.
Definition: Permutations.h:302
std::vector< Vertex > Permutation
Representation of a shape vertex permutation.
Definition: Data.h:35
constexpr bool inPlaceNextPermutation(Container &data, const std::size_t first, const std::size_t last)
In-place next permutation.
Definition: Permutations.h:92
constexpr void inPlaceSwap(Container &data, const std::size_t a, const std::size_t b)
Index-based in-place swapping of elements in an array-like container.
Definition: Permutations.h:56
constexpr Get< 0 > first
Calls std::get<0> on any argument it is invoked with.
Definition: Functor.h:123
constexpr bool inPlacePreviousPermutation(Container &data, const std::size_t first, const std::size_t last)
In-place previous permutation.
Definition: Permutations.h:151