indigoX
combinatronics.hpp
Go to the documentation of this file.
1 #include "triple.hpp"
2 
3 #include <algorithm>
4 #include <iterator>
5 #include <vector>
6 
7 #ifndef INDIGOX_UTIL_COMBINATRONICS_HPP
8 #define INDIGOX_UTIL_COMBINATRONICS_HPP
9 
10 template <class T, class ICT = std::vector<T>> struct CartesianProduct {
11  using type = T;
12  using innerType = ICT;
13 
14  using innerIter = typename innerType::const_iterator;
16  using innerItersC = std::vector<innerIters>;
17 
19  bool finished;
20 
21  CartesianProduct() = delete;
22 
23  template <class outerIter>
24  CartesianProduct(outerIter begin, outerIter end) : finished(false) {
25  for (; begin != end; ++begin)
26  iters.emplace_back(begin->begin(), begin->end(), begin->begin());
27  if (iters.empty()) finished = true;
28  }
29 
31  iters.emplace_back(a.begin(), a.end(), a.begin());
32  iters.emplace_back(b.begin(), b.end(), b.begin());
33  if (a.begin() == a.end() || b.begin() == b.end()) finished = true;
34  }
35 
36  // Returns true if c contains a product, false otherwise
37  bool operator()(innerType &c) {
38  c.clear();
39  if (finished) return false;
40  c.reserve(iters.size());
41  for (auto it : iters) c.push_back(*(it.third));
42 
43  for (auto it = iters.begin();;) {
44  ++(it->third);
45  if (it->third == it->second) {
46  if (it + 1 == iters.end())
47  finished = true;
48  else {
49  it->third = it->first;
50  ++it;
51  }
52  } else
53  break;
54  }
55  return true;
56  }
57 };
58 
59 template <class RandomIt> struct RegionalPermutation {
60  // first, second defines range, third defines current
62  using Iters = std::vector<IterPair>;
63 
64  RandomIt b, e;
67 
68  RegionalPermutation() = delete;
69  RegionalPermutation(RandomIt begin, RandomIt end)
70  : b(begin), e(end), finished(false), first_pass(false) {}
71 
72  bool AddRegion(RandomIt first, RandomIt last) {
73  if (first_pass) return false;
74  if (first == last) return false;
75  RandomIt tmp = last;
76  if (first == --tmp) return false;
77  // Check region doesn't overlap an existing region
78  for (IterPair &be : regions) {
79  if (first < be.first && last <= be.first) continue;
80  if (first >= be.second && last > be.second) continue;
81  return false;
82  }
83  regions.emplace_back(first, last, first);
84  return true;
85  }
86 
87  // Applies the next permutation
88  bool operator()() {
89  if (!first_pass) {
90  first_pass = true;
91  for (IterPair &be : regions) std::sort(be.first, be.second);
92  return true;
93  }
94  for (IterPair &be : regions) {
95  bool fin_region = !std::next_permutation(be.first, be.second);
96  if (!fin_region) return true;
97  }
98  return false;
99  }
100 };
101 
102 #endif /* INDIGOX_UTIL_COMBINATRONICS_HPP */
ICT innerType
Definition: combinatronics.hpp:12
bool AddRegion(RandomIt first, RandomIt last)
Definition: combinatronics.hpp:72
Definition: combinatronics.hpp:10
bool operator()(innerType &c)
Definition: combinatronics.hpp:37
std::vector< IterPair > Iters
Definition: combinatronics.hpp:62
bool operator()()
Definition: combinatronics.hpp:88
RandomIt b
Definition: combinatronics.hpp:64
CartesianProduct(innerType &a, innerType &b)
Definition: combinatronics.hpp:30
Iters regions
Definition: combinatronics.hpp:66
std::vector< innerIters > innerItersC
Definition: combinatronics.hpp:16
Definition: combinatronics.hpp:59
RegionalPermutation()=delete
CartesianProduct()=delete
bool finished
Definition: combinatronics.hpp:65
bool finished
Definition: combinatronics.hpp:19
typename innerType::const_iterator innerIter
Definition: combinatronics.hpp:14
RegionalPermutation(RandomIt begin, RandomIt end)
Definition: combinatronics.hpp:69
Definition: triple.hpp:11
T type
Definition: combinatronics.hpp:11
bool first_pass
Definition: combinatronics.hpp:65
CartesianProduct(outerIter begin, outerIter end)
Definition: combinatronics.hpp:24
RandomIt e
Definition: combinatronics.hpp:64
innerItersC iters
Definition: combinatronics.hpp:18