Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unique combinations of list

Tags:

c#

algorithm

Absolute mind blank on this. It's been one of those days. But I have been looking for a solution for getting unique combinations of a list of items of a certain length. e.g., given a list [a, b, c] and a length of 2, it will return [a,b] [a,c] [b,c] but not [b,a] [c,a] [c,b]

For this I found numerous pieces of code, but none which seems to fit. The following code seemed best fit and I've been trying to alter it for my needs:

// Returns an enumeration of enumerators, one for each permutation
// of the input.
public static IEnumerable<IEnumerable<T>> Permute<T>(IEnumerable<T> list, int count)
{
    if (count == 0)
    {
        yield return new T[0];
    }
    else
    {
        int startingElementIndex = 0;
        foreach (T startingElement in list)
        {
            IEnumerable<T> remainingItems = AllExcept(list, startingElementIndex);

            foreach (IEnumerable<T> permutationOfRemainder in Permute(remainingItems, count - 1))
            {
                yield return Concat<T>(
                    new T[] { startingElement },
                    permutationOfRemainder);
            }
            startingElementIndex += 1;
        }
    }
}

// Enumerates over contents of both lists.
public static IEnumerable<T> Concat<T>(IEnumerable<T> a, IEnumerable<T> b)
{
    foreach (T item in a) { yield return item; }
    foreach (T item in b) { yield return item; }
}

// Enumerates over all items in the input, skipping over the item
// with the specified offset.
public static IEnumerable<T> AllExcept<T>(IEnumerable<T> input, int indexToSkip)
{
    int index = 0;
    foreach (T item in input)
    {
        if (index != indexToSkip) yield return item;
        index += 1;
    }
}

This does what it is supposed to do, but it returns ALL permutations, regardless of them being unique. I've tried to get my head around which piece, if any, of this code to change to get the unique values. Or is the a better way to implement this functionality?

like image 678
anothershrubery Avatar asked Sep 03 '12 13:09

anothershrubery


People also ask

How do you find unique combinations?

The number of combinations of n distinct objects, taken r at a time is: Cr = n! / r! (n - r)!

How do you get all the unique combinations of two lists in Python?

The unique combination of two lists in Python can be formed by pairing each element of the first list with the elements of the second list. Method 1 : Using permutation() of itertools package and zip() function. Approach : Import itertools package and initialize list_1 and list_2.

How do you get all possible combinations without repetition in Python?

A. To create combinations without using itertools, iterate the list one by one and fix the first element of the list and make combinations with the remaining list. Similarly, iterate with all the list elements one by one by recursion of the remaining list.


2 Answers

Try this:

void Main()
{
    var list = new List<string> { "a", "b", "c", "d", "e" };
    var result = GetPermutations(list, 3);
}

IEnumerable<IEnumerable<T>> GetPermutations<T>(IEnumerable<T> items, int count)
{
    int i = 0;
    foreach(var item in items)
    {
        if(count == 1)
            yield return new T[] { item };
        else
        {
            foreach(var result in GetPermutations(items.Skip(i + 1), count - 1))
                yield return new T[] { item }.Concat(result);
        }

        ++i;
    }
}

For a count of 2 it returns this:

a, b
a, c
a, d
a, e
b, c
b, d
b, e
c, d
c, e
d, e

For a count of 3 it returns this:

a, b, c
a, b, d
a, b, e
a, c, d
a, c, e
a, d, e
b, c, d
b, c, e
b, d, e 
c, d, e

Is this what you expect?

like image 169
Daniel Hilgarth Avatar answered Oct 11 '22 16:10

Daniel Hilgarth


In set-speak, what you're looking for is a subset of the power set based on length n. If you do a Google search for "C#" + "Power set" that should give you plenty to get started.

http://en.wikipedia.org/wiki/Power_set

like image 41
Robbie Dee Avatar answered Oct 11 '22 17:10

Robbie Dee