Skip to content

Instantly share code, notes, and snippets.

@jandk
Created April 10, 2013 08:05
Show Gist options
  • Save jandk/5352722 to your computer and use it in GitHub Desktop.
Save jandk/5352722 to your computer and use it in GitHub Desktop.
Permutes a sequence of a specific type, and lets you enumerate through them
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public class PermuteEnumerator<T>
: IEnumerator<IEnumerable<T>>
where T : IComparable
{
T[] _data;
int _length;
bool _isReset = true;
public PermuteEnumerator(IEnumerable<T> data)
{
if (data == null)
throw new ArgumentNullException("data");
_data = data.ToArray();
_length = _data.Length;
Reset();
Current = _data;
}
static void Swap(T[] arr, int a, int b)
{
T tmp = arr[b];
arr[b] = arr[a];
arr[a] = tmp;
}
#region IEnumerator<T> Members
public IEnumerable<T> Current { get; private set; }
public void Dispose() { }
object IEnumerator.Current
{
get { return Current; }
}
public bool MoveNext()
{
if (_isReset)
{
_isReset = false;
return true;
}
// Find the largest i
int i = _length - 2;
while (i >= 0 && _data[i].CompareTo(_data[i + 1]) > 0)
i--;
// If i is smaller than 0, then there are no more permutations.
if (i < 0)
return false;
// Find the largest element after vi but not larger than vi
int k = _length - 1;
while (_data[i].CompareTo(_data[k]) > 0)
k--;
Swap(_data, i, k);
// Swap the last n-i elements
k = 0;
for (int j = i + 1; j < (_length + i) / 2 + 1; j++, k++)
Swap(_data, j, _length - k - 1);
return true;
}
public void Reset()
{
Array.Sort(_data);
_isReset = true;
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment