Skip to content

Commit

Permalink
EnumerableUtils.Combinations()
Browse files Browse the repository at this point in the history
  • Loading branch information
Nixill committed Dec 13, 2023
1 parent 48d1a13 commit 921bf0f
Showing 1 changed file with 39 additions and 0 deletions.
39 changes: 39 additions & 0 deletions CSharp.Nixill/src/Utils/EnumerableUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,45 @@ public static IEnumerable<IEnumerable<T>> PermutationsDistinct<T>(this IEnumerab
elemList.Add(elem);
}
}

// "limit" is non-optional here because 0 would just reutrn basically
// the original list.
//
// Also, this immediately enumerates everything because otherwise it
// would carry a risk of multiple enumeration.
public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> elems, int limit)
{
T[] elemArray = elems.ToArray();

if (limit <= 0) limit += elemArray.Length;
if (limit < 0) return Enumerable.Empty<IEnumerable<T>>();
if (limit >= elemArray.Length) return EnumerableUtils.Of(elems);

return Combs(elemArray, limit);
}

static IEnumerable<IEnumerable<T>> Combs<T>(IEnumerable<T> elemList, int keep)
{
int skips = elemList.Count() - keep;
if (skips == 0)
{
yield return elemList;
yield break;
}

foreach ((T elem, int i) in elemList.Take(skips + 1).WithIndex())
{
if (keep == 1) yield return EnumerableUtils.Of(elem);
else
{
foreach (IEnumerable<T> comb in Combs(elemList.Skip(i + 1), keep - 1))
{
yield return comb.Prepend(elem);
}
}
}
}

public static IEnumerable<T> Repeat<T>(this IEnumerable<T> seq, int count)
{
foreach (int i in Enumerable.Range(0, count))
Expand Down

0 comments on commit 921bf0f

Please sign in to comment.