// // {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)); } } } }
/* Excepted output: * IN: (UO C1, C2) * (UO <C2>, <C1>) * IN: (UO B1, B2),(UO C1, C2) * (UO <B2,C1>, <B1,C2>) * (UO <B1,C1>, <B2,C2>) * IN: (UO A1, A2),(UO B1, B2),(UO C1, C2) * (UO <A1,B2,C1>, <A2,B1,C2>) * (UO <A2,B2,C1>, <A1,B1,C2>) * (UO <A2,B2,C2>, <A1,B1,C1>) * (UO <A2,B1,C1>, <A1,B2,C2>) * IN: (UO A1, A2),(UO 2x B1),(UO C1, C2) * (UO <A1,B1,C1>, <A2,B1,C2>) * (UO <A2,B1,C1>, <A1,B1,C2>) * IN: (UO 2x A1),(UO 2x B1),(UO 2x C1) * (UO 2x <A1,B1,C1>) */ static public void TestPhaseEnumeration() { SpecialFunctions.CheckCondition(UOPair <string> .GetInstance("A1", "A2").Equals(UOPair <string> .GetInstance("A2", "A1")), "real assert"); SpecialFunctions.CheckCondition(UOPair <string> .GetInstance("A1", "A1").ElementsAreSame, "real assert"); SpecialFunctions.CheckCondition(!UOPair <string> .GetInstance("A1", "A2").ElementsAreSame, "real assert"); SpecialFunctions.CheckCondition(UOPair <string> .GetInstance("A1", "A2").ToString() == "(UO A1, A2)" || UOPair <string> .GetInstance("A1", "A2").ToString() == "(UO A2, A1)", "real assert"); SpecialFunctions.CheckCondition(UOPair <string> .GetInstance("A1", "A1").ToString() == "(UO 2x A1)", "real assert"); LinkedList1 <UOPair <string> > small = LinkedList1 <UOPair <string> > .GetInstance(UOPair <string> .GetInstance("C1", "C2")); Debug.WriteLine("IN: " + small.StringJoin(",")); foreach (var phase in UOPair <String> .PhaseEnumeration(small)) { PhasePrinter(phase); } LinkedList1 <UOPair <string> > mid = LinkedList1 <UOPair <string> > .GetInstance(UOPair <string> .GetInstance("B1", "B2"), UOPair <string> .GetInstance("C1", "C2")); Debug.WriteLine("IN: " + mid.StringJoin(",")); foreach (var phase in UOPair <String> .PhaseEnumeration(mid)) { PhasePrinter(phase); } LinkedList1 <UOPair <string> > big = LinkedList1 <UOPair <string> > .GetInstance(UOPair <string> .GetInstance("A1", "A2"), UOPair <string> .GetInstance("B1", "B2"), UOPair <string> .GetInstance("C1", "C2")); Debug.WriteLine("IN: " + big.StringJoin(",")); foreach (var phase in UOPair <String> .PhaseEnumeration(big)) { PhasePrinter(phase); } LinkedList1 <UOPair <string> > dup1 = LinkedList1 <UOPair <string> > .GetInstance(UOPair <string> .GetInstance("A1", "A2"), UOPair <string> .GetInstance("B1", "B1"), UOPair <string> .GetInstance("C1", "C2")); Debug.WriteLine("IN: " + dup1.StringJoin(",")); foreach (var phase in UOPair <String> .PhaseEnumeration(dup1)) { PhasePrinter(phase); } LinkedList1 <UOPair <string> > dup2 = LinkedList1 <UOPair <string> > .GetInstance(UOPair <string> .GetInstance("A1", "A1"), UOPair <string> .GetInstance("B1", "B1"), UOPair <string> .GetInstance("C1", "C1")); Debug.WriteLine("IN: " + dup2.StringJoin(",")); foreach (var phase in UOPair <String> .PhaseEnumeration(dup2)) { PhasePrinter(phase); } }