6#ifndef CPG_COMBINATORICS_HPP
7#define CPG_COMBINATORICS_HPP
22 template<
typename ElementType>
23 auto product_base(std::vector<ElementType>
const&
A, std::vector<ElementType>
const&
B)
25 std::vector< std::vector<ElementType> > result;
26 result.reserve(
A.size() *
B.size() );
31 result.emplace_back( std::vector<ElementType>{a, b} );
37 template<
typename ElementType>
38 auto product_base( std::vector< std::vector<ElementType> >
const& power_set, std::vector<ElementType>
const&
B)
40 std::vector<std::vector<ElementType>> result;
41 result.reserve( power_set.size() *
B.size() );
43 for(
auto& P: power_set)
51 result.emplace_back(
A);
58 template<
typename ElementType,
typename... VectorTypes>
59 auto product_base(std::vector< std::vector<ElementType> >
const& power_set,
60 std::vector<ElementType>
const&
A, std::vector<ElementType>
const&
B, VectorTypes&&... tails)
65 template<
typename ElementType,
typename... VectorTypes>
66 auto product_base(std::vector<ElementType>
const&
A, std::vector<ElementType>
const&
B,
67 std::vector<ElementType>
const& C, VectorTypes&&... tails)
74 template<
typename SetWiseConstra
intType,
typename ElementType>
75 requires requires (SetWiseConstraintType constraint)
77 { constraint( std::vector<ElementType>{} ) } -> std::same_as<bool>;
80 std::vector<ElementType>
const&
A, std::vector<ElementType>
const&
B)
82 std::vector< std::vector<ElementType> > result;
83 result.reserve(
A.size() *
B.size() );
89 auto R = std::vector<ElementType>{a, b};
91 if(set_wise_constraint(R))
92 result.emplace_back( std::move(R) );
99 template<
typename SetWiseConstra
intType,
typename ElementType>
100 requires requires (SetWiseConstraintType constraint)
102 { constraint( std::vector<ElementType>{} ) } -> std::same_as<bool>;
105 std::vector< std::vector<ElementType> >
const& power_set, std::vector<ElementType>
const&
B)
107 std::vector<std::vector<ElementType>> result;
108 result.reserve( power_set.size() *
B.size() );
110 for(
auto& P: power_set)
118 if(set_wise_constraint(
A))
119 result.emplace_back(std::move(
A));
126 template<
typename SetWiseConstraintType,
typename ElementType,
typename... VectorTypes>
127 requires requires (SetWiseConstraintType constraint)
129 { constraint( std::vector<ElementType>{} ) } -> std::same_as<bool>;
131 auto product_base(SetWiseConstraintType&& set_wise_constraint, std::vector< std::vector<ElementType> >
const& power_set,
132 std::vector<ElementType>
const&
A, std::vector<ElementType>
const&
B, VectorTypes&&... tails)
137 template<
typename SetWiseConstraintType,
typename ElementType,
typename... VectorTypes>
138 requires requires (SetWiseConstraintType constraint)
140 { constraint( std::vector<ElementType>{} ) } -> std::same_as<bool>;
143 std::vector<ElementType>
const&
A, std::vector<ElementType>
const&
B,
144 std::vector<ElementType>
const& C, VectorTypes&&... tails)
151 template<
typename ElementType,
typename... VectorTypes>
154 requires ( std::same_as<std::vector<ElementType>, std::remove_cvref_t<VectorTypes>> && ... );
156 auto product(std::vector<ElementType>
const&
A, std::vector<ElementType>
const&
B, VectorTypes... tails)
161 template<
typename SetWiseConstraintType,
typename ElementType,
typename... VectorTypes>
162 requires requires (SetWiseConstraintType constraint)
164 { constraint( std::vector<ElementType>{} ) } -> std::same_as<bool>;
165 requires ( std::same_as<std::vector<ElementType>, std::remove_cvref_t<VectorTypes>> && ... );
167 auto product(SetWiseConstraintType&& set_wise_constraint,
168 std::vector<ElementType>
const&
A, std::vector<ElementType>
const&
B, VectorTypes... tails)
173 template<
typename TransformerType,
typename ElementType,
typename... VectorTypes>
175 std::vector<ElementType>
const&
A, std::vector<ElementType>
const&
B, VectorTypes... tails)
176 requires requires(std::vector<ElementType> v)
178 { transformer(v) } -> std::same_as<std::vector<ElementType>>;
179 requires ( std::same_as<std::vector<ElementType>, std::remove_cvref_t<VectorTypes>> && ... );
186 template<
typename TranformerType,
typename SetWiseConstraintType,
typename ElementType,
typename... VectorTypes>
187 requires requires (SetWiseConstraintType constraint)
189 { constraint( std::vector<ElementType>{} ) } -> std::same_as<bool>;
190 requires ( std::same_as<std::vector<ElementType>, std::remove_cvref_t<VectorTypes>> && ... );
192 auto product(TranformerType&& transformer, SetWiseConstraintType&& set_wise_constraint,
193 std::vector<ElementType>
const&
A, std::vector<ElementType>
const&
B, VectorTypes... tails)
194 requires requires(std::vector<ElementType> v)
196 { transformer(v) } -> std::same_as<std::vector<ElementType>>;
202 template<
typename TranformerType,
typename SetWiseConstraintType,
typename ElementType,
typename... VectorTypes>
203 requires requires (SetWiseConstraintType constraint)
205 { constraint( std::vector<ElementType>{} ) } -> std::same_as<bool>;
206 requires ( std::same_as<std::vector<ElementType>, std::remove_cvref_t<VectorTypes>> && ... );
208 auto product(SetWiseConstraintType&& set_wise_constraint, TranformerType&& transformer,
209 std::vector<ElementType>
const&
A, std::vector<ElementType>
const&
B, VectorTypes... tails)
210 requires requires(std::vector<ElementType> v)
212 { transformer(v) } -> std::same_as<std::vector<ElementType>>;
219 template<
typename ElementType,
typename AllocatorType,
typename T1,
typename T2>
221 std::vector<ElementType, AllocatorType> S, T1 r, T2 m_th,
bool RemoveTails =
false)
223 using T = std::common_type_t<T1, T2>;
228 if( (T)r < (T)1 || (T)n < (T)1 || (T)r > (T)n)
230 if(RemoveTails && S.size() != rr)
231 S.erase(S.begin() + rr, S.end());
240 std::ostringstream os;
242 os << (n-1) <<
"_P_" << (r-1)
245 throw std::runtime_error(os.str());
252 std::size_t s = m_th /
permu;
254 auto begin = S.begin() + rr - r;
256 std::rotate(begin, begin+s, begin+s+1);
262 if( (T)n != (T)0 )
permu /= n;
271 if(RemoveTails && S.size() != rr)
272 S.erase(S.begin() + rr, S.end());
280 template<std::size_t rr,
bool RemoveTails =
false,
281 typename ElementType = int, std::size_t Size = 1,
typename Type =
int>
284 using T =
unsigned long long;
289 auto remove_tails = [&S]() -> std::array<ElementType, rr>
291 std::array<ElementType, rr> SS;
293 for(
size_t i = 0; i < rr; ++i)
294 SS[i] = std::move(S[i]);
299 if( (T)r < (T)1 || (T)n < (T)1 || (T)r > (T)n)
301 if constexpr(RemoveTails && Size != rr)
302 return remove_tails();
311 std::ostringstream os;
313 os << (n-1) <<
"_P_" << (r-1)
316 throw std::runtime_error(os.str());
323 std::size_t s = m_th /
permu;
325 auto begin = S.begin() + rr - r;
327 std::rotate(begin, begin+s, begin+s+1);
333 if( (T)n != (T)0 )
permu /= n;
342 if constexpr(RemoveTails && Size != rr)
343 return remove_tails();
350 template<
typename BiDiIt,
typename Compare>
354 return std::next_permutation(first, last, comp);
358 template<
typename BiDiIt,
typename Compare>
361 using namespace std::placeholders;
368 }
while (std::adjacent_find( first, mid,
369 std::bind(comp, _2, _1) ) != mid );
378 template<
typename ContainerType,
typename BeginType,
typename EndType>
380 BeginType begin, EndType end)
const noexcept
388 template<
typename ContainerType,
typename BeginType,
typename EndType>
390 BeginType begin, EndType end)
const noexcept
392 container.erase(begin, end);
399 template<
typename ContainerType,
typename BeginType,
typename EndType>
401 BeginType begin, EndType end)
const noexcept
403 std::sort(std::execution::par_unseq, begin, end);
410 template<
typename ContainerType,
typename BeginType,
typename EndType>
412 BeginType begin, EndType end)
const noexcept
414 std::sort(std::execution::par_unseq, begin, end);
415 container.erase(container.begin(), begin);
428 template<
typename ElementType,
typename AllocatorType,
430 std::vector<ElementType, AllocatorType>
432 T2 m_th, TailOperationType
const& tail_operation = TailOperationType{})
434 using T = std::common_type_t<T1, T2>;
436 if(r == 0) {
return { }; }
438 if( r == S.size() )
return S;
450 std::ostringstream os;
451 os << (n-1) <<
"_C_" << (r-1) <<
" is too big!";
453 throw std::runtime_error(os.str());
458 if(m_th <
count) --r;
463 auto base = S.begin() + rr - r;
465 std::rotate(base, base + 1, S.end());
471 return tail_operation(S, S.begin() + rr, S.end()) ;
auto product_base(std::vector< ElementType > const &A, std::vector< ElementType > const &B)
constexpr hidden::st_tail_get tail_get
bool next_k_permutation(BiDiIt first, BiDiIt mid, BiDiIt last, Compare comp)
constexpr hidden::st_tail_no_op tail_no_op
std::vector< ElementType, AllocatorType > atomized_permutation(std::vector< ElementType, AllocatorType > S, T1 r, T2 m_th, bool RemoveTails=false)
std::vector< ElementType, AllocatorType > atomized_combination(std::vector< ElementType, AllocatorType > S, T1 r, T2 m_th, TailOperationType const &tail_operation=TailOperationType{})
bool next_combination(BiDiIt first, BiDiIt mid, BiDiIt last, Compare comp)
constexpr hidden::st_tail_sort tail_sort
constexpr hidden::st_tail_remove tail_remove
auto product(std::vector< ElementType > const &A, std::vector< ElementType > const &B, VectorTypes... tails)
auto nCr(unsigned long long n, unsigned long long r) noexcept
auto nPr(unsigned long long n, unsigned long long r=1) noexcept
constexpr auto reverse(sequence< ms... > mm, sequence< rs... >)
enable_if_all_in_list_t< types::type_list_t< Type1, Type2 >, integral_list_t, ReturnType > npr(Type1 nn, Type2 rr)
enable_if_all_in_list_t< types::type_list_t< Type1, Type2 >, integral_list_t, ReturnType > ncr(Type1 nn, Type2 rr)
ContainerType< EleType > sort(ContainerType< EleType, Types... > container, sort_order order=sort_order::ascending, sort_method method=sort_method::size)
ContainerType & operator()(ContainerType &container, BeginType begin, EndType end) const noexcept
ContainerType & operator()(ContainerType &container, BeginType begin, EndType end) const noexcept
ContainerType & operator()(ContainerType &container, BeginType begin, EndType end) const noexcept
ContainerType & operator()(ContainerType &container, BeginType begin, EndType end) const noexcept