0

It is an extension of this problem - Super set in a list:

Getting all possible combinations from a list of numbers

This helps, but returns all sub-sets: http://rosettacode.org/wiki/Power_set#C.23

But what I need is to retrieve only the sub-sets that have a fixed number. I.e. say my list is a collection of numbers:

1 2 3 4 5 6

I only want the different combinations for an exact 4 numbers, i.e. 1,2,3,4 1,2,3,5 1,2,3,6 1,3,4,5 1,3,4,6 1,4,5,6 2,3,4,5 2,3,4,6 2,4,5,6 3,4,5,6

I am using numbers as an example, but in my solution I am dealing with other types of objects.

TylerH
  • 20,799
  • 66
  • 75
  • 101
SomeOne
  • 5
  • 2
  • 1
    You could use the solution you provided, then check the length and != 4 then get rid of it. I'm not that great at understanding Linq to be honest, so I have a hard time understanding what is really going on there. – Radmation Jul 13 '16 at 21:21
  • You'd still do all the work of generating the sets you're going to throw out, but you could use a linq .Where(x => x.length == 4); – GWhite Jul 13 '16 at 21:32

2 Answers2

0

Assuming you always want exactly 4, it's a relatively easy algorithm to write using nested for loops.

var set = new[] {1, 2, 3, 4, 5, 6};

for (int firstIndex = 0; firstIndex < set.Length; firstIndex++)
{
    for (int secondIndex = firstIndex+1; secondIndex < set.Length; secondIndex++)
    {
        for (int thirdIndex = secondIndex+1; thirdIndex < set.Length; thirdIndex++)
        {
            for (int fourthIndex = thirdIndex+1; fourthIndex < set.Length; fourthIndex++)
            {
                Console.WriteLine(string.Format($"{set[firstIndex]}, {set[secondIndex]}, {set[thirdIndex]}, {set[fourthIndex]}"));
            }
        }
    }
}

If you need it to be dynamic and support different list sizes (i.e. it's not always 4) then it's probably easier to convert into a recursive call that recurses N times.

Tim Copenhaver
  • 3,282
  • 13
  • 18
0

You can extend the solution you referenced by filtering on the length of the results

public IEnumerable<IEnumerable<T>> GetPowerSetOfLength<T>(List<T> list, int length)
{
    return from m in Enumerable.Range(0, 1 << list.Count)
              //because doing a count will iterate through the enumerable 
              //better to just convert it to a list up front 
              let setResult = ( from i in Enumerable.Range(0, list.Count)
                                where (m & (1 << i)) != 0
                                select list[i]).ToList()
              where setResult.Count==length
              select setResult;
}

Here's a link to a dot net fiddle that is using this code if you want to test it out

konkked
  • 3,161
  • 14
  • 19