Skip to content

Instantly share code, notes, and snippets.

@lavn0
Created January 29, 2018 16:12
Show Gist options
  • Save lavn0/44878f1f6bed3df9fcb4352608657321 to your computer and use it in GitHub Desktop.
Save lavn0/44878f1f6bed3df9fcb4352608657321 to your computer and use it in GitHub Desktop.
組み合わせとか順列とか
public static class SetUtil
{
/// <summary>組み合わせ</summary>
public static IEnumerable<IEnumerable<T>> Combination<T>(this IEnumerable<T> items, int r)
{
if (r == 0)
{
yield return Enumerable.Empty<T>();
yield break;
}
int i = 1;
foreach (var item in items)
foreach (var c in Combination(items.Skip(i++), r - 1))
yield return c.Before(item);
}
/// <summary>順列</summary>
public static IEnumerable<IEnumerable<T>> Permutation<T>(this IEnumerable<T> items, int? k = null)
{
if (k == null) k = items.Count();
if (k == 0)
{
yield return Enumerable.Empty<T>();
yield break;
}
int i = 1;
foreach (var item in items)
foreach (var p in Permutation(items.Where((_, index) => i++ != index), k - 1))
yield return p.Before(item);
}
private static IEnumerable<T> Before<T>(this IEnumerable<T> items, T first)
{
yield return first;
foreach (var item in items) yield return item;
}
/// <summary>複数のリストから一つずつ取り出した組み合わせを作る</summary>
public static IEnumerable<List<T>> GetCombinationSets<T>(List<List<T>> items)
{
var counter = new int[items.Count];
do
{
yield return items.Zip(counter, (item, index) => item.ElementAt(index)).ToList();
} while (CountUp(items, counter));
}
private static bool CountUp<T>(List<List<T>> items, int[] counter)
{
int index = counter.Length - 1;
counter[index]++;
while (counter[index] >= items.ElementAt(index).Count)
{
counter[index] = 0;
index--;
if (index < 0) return false;
counter[index]++;
}
return index >= 0;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment