internal Set <Set <Set <T> > > GetAllPartitions() { var firstPartition = new Set <Set <T> >() { this }; var result = new Set <Set <Set <T> > >() { firstPartition }; MakeAllPartititionsOfCurrentSet(firstPartition); return(result); void MakeAllPartititionsOfCurrentSet(Set <Set <T> > currentSet) { foreach (var set in currentSet) { if (set.Count > 1) { var workSet = new Set <T>(set); var rest = new Set <Set <T> >(currentSet); rest.Remove(set); if (workSet.Count < 2) { return; } var bitMask = new BitMask(workSet.Count); while (bitMask.SetToNextCombination()) { MakeSmallPartition(workSet, bitMask, out Set <T> leftSet, out Set <T> rightSet); if ((leftSet.Count == 0) || (rightSet.Count == 0)) { continue; } var smallSet = new Set <Set <T> >(rest); smallSet.Add(leftSet); smallSet.Add(rightSet); if (result.Contains(smallSet)) { continue; } result.Add(smallSet); MakeAllPartititionsOfCurrentSet(smallSet); } } }
static void MakeSmallPartition(Set <T> workSet, BitMask bitMask, out Set <T> leftSet, out Set <T> rightSet) { var setEnum = workSet.GetEnumerator(); var bitMaskEnum = bitMask.GetEnumerator(); rightSet = new Set <T>(); leftSet = new Set <T>(); while (bitMaskEnum.MoveNext() && setEnum.MoveNext()) { if (bitMaskEnum.Current) { leftSet.Add(setEnum.Current); } else { rightSet.Add(setEnum.Current); } } }