oleksii
11/8/2013 - 11:48 PM

Extension method for genereting all permutations in lexicographic order for selected array of elements.

Extension method for genereting all permutations in lexicographic order for selected array of elements.

// http://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order
public static IEnumerable<TRes> AllPermutationsWithSelector<TSource, TRes>(this TSource[] seq, Func<IEnumerable<TSource>, TRes> selector)
{
	int n = seq.Length;
	var arr = Enumerable.Range(0, n).ToArray();

	while (true)
	{
		// Building result string, then generating next permutation
		yield return selector(arr.Select(i => seq[i]));

		// Finding largest k such that a[k] > a[k - 1]
		int k = n;
		while (--k > 0 && (arr[k] < arr[k - 1])) { }
		if (k == 0) yield break;
		int temp = arr[k - 1];

		// Finding largest l such that a[l] > a[k]
		int l = seq.Length;
		while (arr[--l] < temp) { }

		// Swap values
		arr[k - 1] = arr[l];
		arr[l] = temp;

		// Reversing the sequence from a[k] up to a[n]
		for (int i = 0; i < (n - k) / 2; i++)
		{
			temp = arr[i + k];
			arr[i + k] = arr[n - 1 - i];
			arr[n - 1 - i] = temp;
		}
	}
}