Skip to content

Instantly share code, notes, and snippets.

@NikiforovAll
Last active October 19, 2020 20:23
Show Gist options
  • Save NikiforovAll/b4a8e22b088644dbd0bc885b19ffb72b to your computer and use it in GitHub Desktop.
Save NikiforovAll/b4a8e22b088644dbd0bc885b19ffb72b to your computer and use it in GitHub Desktop.
csharp-loves-patterns
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqProviderExample
{
public class PermutationsSource
{
public PermutationsSource(params string[] words) => this.words = words;
private readonly HashSet<string> _generated = new();
private readonly string[] words;
public IEnumerable<T> SelectMany<T>(
Func<PermutationsSource, IEnumerable<string>> selector,
Func<PermutationsSource, string, T> resultSelector) =>
selector(this).Select(i => resultSelector(this, i));
public PermutationsSource Select(Func<PermutationsSource, PermutationsSource> selection) =>
selection(this);
public IEnumerable<string> Permute()
{
foreach (var item in words)
if (!_generated.Add(item))
foreach (var perm in item.Permutations())
yield return new string(perm.ToArray());
}
}
public static class PermutationsExtensions
{
public static IEnumerable<IEnumerable<T>> Permutations<T>(this IEnumerable<T> source) =>
GPermutations(source.ToArray());
private static IEnumerable<IEnumerable<T>> GPermutations<T>(IEnumerable<T> source)
{
var c = source.Count();
if (c == 1)
yield return source;
else
for (int i = 0; i < c; i++)
foreach (var p in GPermutations(source.Take(i).Concat(source.Skip(i + 1))))
yield return source.Skip(i).Take(1).Concat(p);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment