Skip to content

Instantly share code, notes, and snippets.

@JohanLarsson
Last active December 18, 2015 00:38
Show Gist options
  • Save JohanLarsson/5697899 to your computer and use it in GitHub Desktop.
Save JohanLarsson/5697899 to your computer and use it in GitHub Desktop.
public static class ListExt
{
public static IEnumerable<T[]> GetSubsets<T>(this List<T> set, int subsetLength)
{
int[] indices = Enumerable.Range(0, subsetLength).ToArray();
while (true)
{
yield return indices.Select(i => set[i]).ToArray();
indices = Increment(indices, set.Count - 1);
if (indices == null)
break;
}
}
/// <summary>
/// Updates the indices to sample subset for next iteration
/// </summary>
/// <param name="indices"></param>
/// <param name="max"></param>
/// <returns></returns>
private static int[] Increment(int[] indices, int max)
{
for (int i = indices.Length - 1; i >= 0; i--)
{
if (CanIncrement(indices, max, i))
{
int ci = indices[i] + 1;
indices[i] = ci;
ResetAfter(indices, i, ci);
return indices;
}
}
return null;
}
private static void ResetAfter(int[] indices, int startIndex, int startValue)
{
for (int i = startIndex + 1; i < indices.Length; i++)
{
startValue++;
indices[i] = startValue;
}
}
private static bool CanIncrement(int[] indices, int max, int i)
{
return indices[i] < (max - (indices.Length - 1 - i));
}
}
@Mellen
Copy link

Mellen commented Jun 4, 2013

I figured it out with sets in Haskell:

import Data.Set
import Data.List

makeallsets [] n = fromList []
makeallsets xs 1 = fromList [[x] | x <- xs]
makeallsets xs n = fromList [sort([x] ++ y) | x <- xs, y <- toAscList(makeallsets xs (n - 1))] 

It's pretty slow, though. I think we can get it faster if we use only sets and don't go from lists to sets.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment