Example #1
0
        //

        // {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));
                    }
                }
            }
        }