1 #ifndef _COMBINATORIAL_HPP 2 #define _COMBINATORIAL_HPP 13 #include <containers/Vector.hpp> 14 #include <debug/Crash.hpp> 15 #include <ios/Logger.hpp> 41 const Slot& firstSlot,
42 const Slot& pastLastSlot,
47 for(Slot iSlot=firstSlot;
84 const Slot pastLastSlot=
93 sign(pastLastSlot-firstSlot);
96 const Int nResObjToAss=
101 CRASH<<
"Should have ended without objects to assign, have: "<<nResObjToAss;
114 nMaxPerSlot.summatorial()>=nObj;
178 while(
not found
and iSlot<
nSlots()-1)
212 Int nUpToPreviousSlot=
307 const bool lastOrFirst=
false)
311 if(
not isPossibleToAccomodate(nMaxPerSlot,nObj))
312 CRASH<<
"Can accommodate at most "<<nMaxObj()<<
" objects but "<<nObj<<
" asked";
315 if(lastOrFirst==
false)
327 template <
typename Int,
338 if(
Combinatorial<Int>::isPossibleToAccomodate(nMaxPerSlot,nObj))
357 while(combo.rewindOrAdvance(BackForw));
368 template <
typename I,
387 const std::map<I,I> indepFactsAndMax=
391 const Vector<I> indepFacts=
392 getAllKeys(indepFactsAndMax);
395 const Vector<I> nMaxPerFact=
396 getAllVal(indepFactsAndMax);
403 const int nIndepFacts=
410 for(
int nFactsTaken=0;
414 loopOnAllCombinations(nMaxPerFact,
416 [&fun,&nIndepFacts,&indepFacts](
const Vector<I>& takenPerIndepFact)
423 iIndepFact<nIndepFacts;
426 iTaken<=takenPerIndepFact[iIndepFact];
429 indepFacts[iIndepFact];
448 template <
typename Fun,
456 loopOnAllCombinations(
Vector<INToPart>(nOfPart,nToPart),nToPart,fun);
void moveLeft(const Slot &iSlot)
Move left one element from the slot.
Int loopOnAllCombinations(const Vector< Int > &nMaxPerSlot, const int nObj, const Fun &fun, BACK_FORW BackForw=FORW)
Combinatorial(const Vector< Int > &nMaxPerSlot, const int nObj, const bool lastOrFirst=false)
Constructor specifying the maximal number of objects per slot.
Int nObj
Number of objects.
#define CRASH
Initialize the crasher.
Int nMaxObj() const
Maximal number of objects that can be accommodated.
bool canBeMovedRight(const Slot &iSlot) const
Check if 1 object can be moved from the slot to the right one.
bool isSlotFullyOccupied(const Slot &iSlot) const
Check if the slot is fully occupied.
bool canBeMovedLeft(const Slot &iSlot) const
Check if 1 object can be moved from the slot to the left one.
BACK_FORW
Enumerate the possibity to loop backward or forward.
I loopOnAllSubmultiplesOf(const I &i, const F &fun, const BACK_FORW &backForw=FORW)
decltype(auto) operator()(Ts &&...ts)
Vector< Int > getFirst() const
Get the firt combo.
void divWithMod(Vector< TOut > "ient, Vector< TOut > &remainder, const Vector &divisor) const
Returns the result and remainder of the division.
bool isSlotFree(const Slot &iSlot) const
Check if the slot is free.
void setToLast()
Set to last combo.
Vector< Int > nMaxPerSlot
Maximal number of objects per slot.
bool rewind()
Go to previous combo, returning true if was possible to do it.
Vector< Int > getLast() const
Get the last combo.
static bool isPossibleToAccomodate(const Vector< Int > &nMaxPerSlot, const int nObj)
Check if it is possible to combine the nObj into the slots.
const Vector< Int > & operator()() const
Const cast to the combinatorial.
FIRST_OR_LAST
Enumerate first and last.
void moveRight(const Slot &iSlot)
Move right one element from the slot.
#define PROVIDE_ALSO_NON_CONST_METHOD(NAME)
void setToFirst()
Set to first combo.
Vector< Int > getFirstOrLast(const FIRST_OR_LAST &firstLast) const
Get the first or last combo.
bool rewindOrAdvance(const BACK_FORW &BackForw)
Go backward or advance depending on the passed parameter.
auto loopOnAllAdditivePartitioningOf(const INpart &nOfPart, const INToPart &nToPart, const Fun &fun)
Slot nSlots() const
Number of slots.
bool advance()
Go to next combo, returning true if was possible to do it.
Vector< Int > nPerSlot
Current combination.
Int assignToSlots(Vector< Int > &res, Int nObjToAss, const Slot &firstSlot, const Slot &pastLastSlot, const Slot &dSlot) const