// // {A1,A2} -> {<A1>,<A2>} // {A1,A2},{B1,B2} -> {<A1,B1>,<A2,B2>}, {<A1,B2>,<A2,B1>} // {A1,A2},{B1,B2},{C1,C2} -> // foreach pair in C({B1,B2},{C1,C2}) // If duplex // yeild return pair.First + c1, pair.second + c2 // yeild return pair.First + c2, pair.second + c1 // else // yeild return pair.First + c2, pair.second + c1 // {A1},{B1,B2} -> {<A1,B1>,<A1,B2>} // {A1} -> {<A1>,<A1>} -> {<A1>} // {A1},{B1} -> {<A1,B1>,<A1,B1>} -> {<A1,B1>} //Every item enumerated is unique static public IEnumerable <UOPair <LinkedList1 <T> > > PhaseEnumeration(LinkedList1 <UOPair <T> > uOPairList) { //Use of a singlely-linked list makes this very efficient. if (null == uOPairList) { yield return(UOPair <LinkedList1 <T> > .GetInstance(null, null)); yield break; } UOPair <T> firstPair = uOPairList.First(); foreach (UOPair <LinkedList1 <T> > resultsFromRest in PhaseEnumeration(uOPairList.RestOrNull)) { if (resultsFromRest.ElementsAreSame) { if (firstPair.ElementsAreSame) { LinkedList1 <T> a0b0 = LinkedList1 <T> .GetInstance(firstPair.First, resultsFromRest.First); yield return(UOPair <LinkedList1 <T> > .GetInstance(a0b0, a0b0)); } else { LinkedList1 <T> a1b0 = LinkedList1 <T> .GetInstance(firstPair.First, resultsFromRest.First); LinkedList1 <T> a2b0 = LinkedList1 <T> .GetInstance(firstPair.Second, resultsFromRest.First); yield return(UOPair <LinkedList1 <T> > .GetInstance(a1b0, a2b0)); } } else { if (firstPair.ElementsAreSame) { LinkedList1 <T> a0b1 = LinkedList1 <T> .GetInstance(firstPair.First, resultsFromRest.First); LinkedList1 <T> a0b2 = LinkedList1 <T> .GetInstance(firstPair.First, resultsFromRest.Second); yield return(UOPair <LinkedList1 <T> > .GetInstance(a0b1, a0b2)); } else { LinkedList1 <T> a1b1 = LinkedList1 <T> .GetInstance(firstPair.First, resultsFromRest.First); LinkedList1 <T> a2b2 = LinkedList1 <T> .GetInstance(firstPair.Second, resultsFromRest.Second); yield return(UOPair <LinkedList1 <T> > .GetInstance(a1b1, a2b2)); LinkedList1 <T> a1b2 = LinkedList1 <T> .GetInstance(firstPair.First, resultsFromRest.Second); LinkedList1 <T> a2b1 = LinkedList1 <T> .GetInstance(firstPair.Second, resultsFromRest.First); yield return(UOPair <LinkedList1 <T> > .GetInstance(a1b2, a2b1)); } } } }