Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
ah-comb.H
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 version 2.0.0b
6 https://github.com/lrleon/Aleph-w
7
8 This file is part of Aleph-w library
9
10 Copyright (c) 2002-2026 Leandro Rabindranath Leon
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29*/
30
31# ifndef COMB_H
32# define COMB_H
33
53# include <htlist.H>
54# include <tpl_dynDlist.H>
55# include <tpl_dynArray.H>
56# include <tpl_array.H>
57# include <tpl_dynSetTree.H>
58# include <ahSort.H>
59
60namespace Aleph
61{
63 namespace comb_detail
64 {
78 template <typename T>
79 [[nodiscard]] inline
80 DynList<DynList<T>> transpose_impl(DynList<DynList<T>> & l)
81 {
82 if (l.is_empty())
83 return {};
84
86
87 size_t ncol = 0; {
88 const HTList & lrow = l.get_first();
90 for (HTList::Iterator it(lrow); it.has_curr(); it.next_ne(), ++ncol)
91 row.append(static_cast<Snodenc<T> *>(it.get_curr()));
92 mat.append(std::move(row));
93 }
94
95 size_t nrow = 1;
96 for (auto row_it = l.get_it(1); row_it.has_curr(); row_it.next_ne(), ++nrow)
97 {
98 const HTList & lrow = row_it.get_curr();
100 row.reserve(ncol);
101 size_t col = 0;
102 for (HTList::Iterator it(lrow); it.has_curr(); it.next_ne(), ++col)
103 row.append(static_cast<Snodenc<T> *>(it.get_curr()));
104
105 assert(col == ncol);
106
107 mat.append(std::move(row));
108 }
109
111 for (size_t j = 0; j < ncol; ++j)
112 {
114 for (size_t i = 0; i < nrow; ++i)
115 row.append(mat(i)(j)->get_data());
116
117 ret.append(std::move(row));
118 }
119
120 return ret;
121 }
122 } // namespace comb_detail
124
138 template <typename T>
139 [[nodiscard]] inline
141 {
142 if (l.is_empty())
143 return {};
144
145 Array<Array<T>> mat;
146
147 for (auto it = l.get_it(); it.has_curr(); it.next_ne())
148 mat.append(it.get_curr());
149
150 const size_t nrow = mat.size();
151 const size_t ncol = mat[0].size();
152
153 for (size_t i = 1; i < nrow; ++i)
154 assert(mat[i].size() == ncol);
155
157
158 for (size_t j = 0; j < ncol; ++j)
159 {
161 for (size_t i = 0; i < nrow; ++i)
162 row.append(mat(i)(j));
163
164 ret.append(std::move(row));
165 }
166
167 return ret;
168 }
169
170
189 template <template <typename> class C, typename T>
190 inline
192 {
193 C<C<T>> mat;
194
195 const size_t nrow = l.size();
196 if (nrow == 0)
197 return;
198
199 const size_t ncol = l.get_first().size();
200
201 for (size_t i = 0; i < nrow; ++i)
202 assert(l(i).size() == ncol);
203
204 for (size_t j = 0; j < ncol; ++j)
205 {
206 C<T> row;
207 for (size_t i = 0; i < nrow; ++i)
208 row.append(std::move(l(i)(j)));
209 mat.append(std::move(row));
210 }
211 l.swap(mat);
212 }
213
227 template <typename T>
228 inline
230 {
231 if (l.is_empty())
232 return;
233
235
236 size_t ncol = 0; {
239 for (; not lrow.is_empty(); ++ncol)
241 mat.append(std::move(row));
242 }
243
244 size_t nrow = 1;
245 for (; not l.is_empty(); ++nrow)
246 {
249 row.reserve(ncol);
250 size_t col = 0;
251 while (not lrow.is_empty())
252 {
254 ++col;
255 }
256
257 assert(col == ncol);
258
259 mat.append(std::move(row));
260 }
261
262 assert(l.is_empty());
263
264 for (size_t j = 0; j < ncol; ++j)
265 {
267 for (size_t i = 0; i < nrow; ++i)
268 {
269 Slinknc *node_ptr = mat(i)(j);
270 row.HTList::append(static_cast<Snodenc<T> *>(node_ptr));
271 }
272 l.append(std::move(row));
273 }
274 }
275
277
290 template <typename T, class Op>
291 static inline
293 DynList<typename DynList<T>::Iterator> & its, Op & op)
294 {
295 if (its.is_empty())
296 return op(sample.template maps<T>([](const T & i) { return i; }));
297
298 auto itor = its.remove_first();
299 for (auto it = itor; it.has_curr(); it.next_ne())
300 {
301 auto item = it.get_curr();
302 sample.insert(item);
304 {
306 its.insert(itor);
307 return false;
308 }
310 }
311 its.insert(itor);
312
313 return true;
314 }
315
317
353 template <typename T, class Op>
354 inline
355 bool traverse_perm(const DynList<DynList<T>> & l, Op & op)
356 {
357 using IT = typename DynList<T>::Iterator;
359
360 { // This block allows getting a constant copy of l and then reverse
361 // it. At the end of block lcpy memory is freed
362 const DynList<IT> lcpy =
363 l.template maps<IT>([](const auto & l) { return l.get_it(); });
364 its = lcpy.rev();
365 }
366
368 return traverse_perm_impl(ll, its, op);
369 }
370
375 template <typename T, class Op>
376 inline
377 bool traverse_perm(const DynList<DynList<T>> & l, Op && op)
378 {
379 return traverse_perm(l, op);
380 }
381
393 template <typename T, class Op>
394 inline
395 void for_each_perm(const DynList<DynList<T>> & l, Op & op)
396 {
397 traverse_perm(l, [&op](const auto & row)
398 {
399 op(row);
400 return true;
401 });
402 }
403
408 template <typename T, class Op>
409 inline
410 void for_each_perm(const DynList<DynList<T>> & l, Op && op)
411 {
412 return for_each_perm(l, op);
413 }
414
425 template <typename T>
426 [[nodiscard]]
428 {
430 for_each_perm(l, [&ret](const DynList<T> & perm) { ret.append(perm); });
431 return ret;
432 }
433
446 template <typename T>
447 [[nodiscard]]
449 {
451
452 for_each_perm(l, [&combs](const DynList<T> & perm)
453 {
455 combs.insert(std::move(comb));
456 });
457
458 return combs.
459 template maps<DynList<T>>([](const DynList<T> & comb) { return comb; });
460 }
461
477 template <typename T, typename Tc, class Op = Dft_Fold_Op<Tc, T>>
478 [[nodiscard]]
479 T fold_perm(const T & init, const DynList<DynList<Tc>> & l, Op & op)
480 {
481 T acu = init;
482 traverse_perm(l, [&op, &acu](const auto & l)
483 {
484 acu = op(acu, l);
485 return true;
486 });
487 return acu;
488 }
489
494 template <typename T, typename Tc, class Op = Dft_Fold_Op<Tc, T>>
495 [[nodiscard]]
496 T fold_perm(const T & init, const DynList<DynList<Tc>> & l, Op && op)
497 {
498 return fold_perm(init, l, op);
499 }
500
512 template <typename T>
513 [[nodiscard]]
515 {
516 size_t count = 1;
517 for (auto it = l.get_it(); it.has_curr(); it.next_ne())
518 {
519 const size_t sz = it.get_curr().size();
520 if (sz == 0)
521 return 0; // Any empty list results in no permutations
522 count *= sz;
523 }
524 return count;
525 }
526
539 template <typename T, class Pred>
540 [[nodiscard]]
542 {
543 bool found = false;
544 traverse_perm(l, [&pred, &found](const DynList<T> & perm)
545 {
546 if (pred(perm))
547 {
548 found = true;
549 return false; // stop
550 }
551 return true;
552 });
553 return found;
554 }
555
560 template <typename T, class Pred>
561 [[nodiscard]]
563 {
564 return exists_perm(l, pred);
565 }
566
579 template <typename T, class Pred>
580 [[nodiscard]]
582 {
583 return traverse_perm(l, pred);
584 }
585
590 template <typename T, class Pred>
591 [[nodiscard]]
593 {
594 return all_perm(l, pred);
595 }
596
609 template <typename T, class Pred>
610 [[nodiscard]]
612 {
613 return not exists_perm(l, pred);
614 }
615
620 template <typename T, class Pred>
621 [[nodiscard]]
623 {
624 return none_perm(l, pred);
625 }
626
637 template <typename T, class Pred>
638 [[nodiscard]]
640 {
642 for_each_perm(l, [&ret, &pred](const DynList<T> & perm)
643 {
644 if (pred(perm))
645 ret.append(perm);
646 });
647 return ret;
648 }
649
654 template <typename T, class Pred>
655 [[nodiscard]]
657 {
658 return filter_perm(l, pred);
659 }
660
672 template <typename R, typename T, class Op>
673 [[nodiscard]]
675 {
677 for_each_perm(l, [&ret, &op](const DynList<T> & perm)
678 {
679 ret.append(op(perm));
680 });
681 return ret;
682 }
683
688 template <typename R, typename T, class Op>
689 [[nodiscard]]
691 {
692 return map_perm<R>(l, op);
693 }
694}
695
696# endif // COMB_H
High-level sorting functions for Aleph containers.
Simple dynamic array with automatic resizing and functional operations.
Definition tpl_array.H:138
constexpr size_t size() const noexcept
Return the number of elements stored in the stack.
Definition tpl_array.H:333
T & append(const T &data)
Append a copy of data
Definition tpl_array.H:239
Iterator on the items of list.
Definition htlist.H:1714
Dynamic singly linked list with functional programming support.
Definition htlist.H:1423
T & insert(const T &item)
Insert a new item by copy.
Definition htlist.H:1502
T & append(const T &item)
Append a new item by copy.
Definition htlist.H:1562
T & get_first() const
Return the first item of the list.
Definition htlist.H:1675
DynList & rev() noexcept
Definition htlist.H:1769
DynList & swap(DynList &l) noexcept
Swap this with l.
Definition htlist.H:1448
Dynamic set backed by balanced binary search trees with automatic memory management.
Iterator on HTList.
Definition htlist.H:1083
bool has_curr() const noexcept
Return true if iterator has current item.
Definition htlist.H:1150
Single linked list of nodes.
Definition htlist.H:507
constexpr bool is_empty() const noexcept
Return true if list is empty.
Definition htlist.H:523
Slinknc * remove_head()
Definition htlist.H:777
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
Link of a single linked list non-circular and without header node.
Definition htlist.H:100
Node belonging to a single non-circular linked list without header node.
Definition htlist.H:328
auto get_it() const
Return a properly initialized iterator positioned at the first item on the container.
Definition ah-dry.H:190
Singly linked list implementations with head-tail access.
Freq_Node * pred
Predecessor node in level-order traversal.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
bool none_perm(const DynList< DynList< T > > &l, Pred &pred)
Check if no permutation satisfies a predicate.
Definition ah-comb.H:611
DynList< DynList< T > > build_combs(const DynList< DynList< T > > &l)
Build the set of unique combinations from a list of lists.
Definition ah-comb.H:448
DynList< R > map_perm(const DynList< DynList< T > > &l, Op &op)
Transform each permutation via a mapping operation.
Definition ah-comb.H:674
size_t size(Node *root) noexcept
T fold_perm(const T &init, const DynList< DynList< Tc > > &l, Op &op)
Left-fold over all permutations.
Definition ah-comb.H:479
size_t perm_count(const DynList< DynList< T > > &l)
Count the total number of permutations from a list of lists.
Definition ah-comb.H:514
bool traverse_perm(const DynList< DynList< T > > &l, Op &op)
Traverse all the possible permutations that can be done of a list of lists and on each permutation pe...
Definition ah-comb.H:355
DynList< DynList< T > > filter_perm(const DynList< DynList< T > > &l, Pred &pred)
Filter permutations that satisfy a predicate.
Definition ah-comb.H:639
std::decay_t< typename HeadC::Item_Type > T
Definition ah-zip.H:107
DynArray< T > sort(const DynArray< T > &a, Cmp &&cmp=Cmp())
Returns a sorted copy of a DynArray.
Definition ahSort.H:227
void for_each_perm(const DynList< DynList< T > > &l, Op &op)
Apply a procedure to every permutation produced by traverse_perm.
Definition ah-comb.H:395
DynList< DynList< T > > transpose(const DynList< DynList< T > > &l)
Transpose a matrix represented as a list of lists.
Definition ah-comb.H:140
DynList< DynList< T > > build_perms(const DynList< DynList< T > > &l)
Materialize all permutations from a list of lists.
Definition ah-comb.H:427
static bool init
Definition hash-fct.C:47
void in_place_transpose(C< C< T > > &l)
In-place transpose of a rectangular matrix stored as a nested container.
Definition ah-comb.H:191
bool exists_perm(const DynList< DynList< T > > &l, Pred &pred)
Check if any permutation satisfies a predicate.
Definition ah-comb.H:541
bool all_perm(const DynList< DynList< T > > &l, Pred &pred)
Check if all permutations satisfy a predicate.
Definition ah-comb.H:581
DynList< T > maps(const C &c, Op op)
Classic map operation.
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Definition ahAlgo.H:127
AVL binary search tree with nodes without virtual destructor.
Definition tpl_avl.H:704
Dynamic array container with automatic resizing.
Lazy and scalable dynamic array implementation.
Dynamic doubly linked list implementation.
Dynamic set implementations based on balanced binary search trees.
DynList< int > l