I have a class called GenericPermutations that is both enumerable and an enumerator. Its job is to take an ordered list of objects and iterate through each permutation of t
Reduce your confusion (?) by using the generic versions of IEnumerable
and IEnumerator
.
A permutation enumerable is IEnumerable
. So you might have something like
IEnumerable> GetPermutations(IEnumerable sequence)
{
return new Permuter(sequence);
}
and
public class Permuter : IEnumerable> { ... }
Furthermore, I've seen more than one case where a single type implemented both IEnumerable
and IEnumerator
; its GetEnumerator method was simply return this;
.
I think such a type would need to be a struct, though, because if it were a class you'd have all sorts of problems if you called GetEnumerator() a second time before the first enumeration was completed.
EDIT: Consuming the permuter
var permuter = GetPermutations(sequence);
foreach (var permutation in permuter)
{
foreach (var item in permutation)
Console.Write(item + "; ");
Console.WriteLine();
}
Assuming the input sequence is { 1, 2, 3 }, the output is
1; 2; 3;
1; 3; 2;
2; 1; 3;
2; 3; 1;
3; 1; 2;
3; 2; 1;
EDIT:
Here's a super-inefficient implementation to illustrate the suggestion:
public class Permuter : IEnumerable>
{
private readonly IEnumerable _sequence;
public Permuter(IEnumerable sequence)
{
_sequence = sequence;
}
public IEnumerator> GetEnumerator()
{
foreach(var item in _sequence)
{
var remaining = _sequence.Except(Enumerable.Repeat(item, 1));
foreach (var permutation in new Permuter(remaining))
yield return Enumerable.Repeat(item, 1).Concat(permutation);
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}