// ************************************************************************ /// <summary> /// Sort Index is 0 based and should be less than MaxIndex. Otherwise you get an exception. /// </summary> /// <param name="sortIndex"></param> /// <param name="result">Value is not used as inpu, only as output. Re-use buffer in order to save memory</param> /// <returns></returns> public void GetSortedValuesFor(long sortIndex) { int size = _sortedValues.Length; if (sortIndex < 0) { throw new ArgumentException("sortIndex should greater or equal to 0."); } if (sortIndex >= MaxIndex) { throw new ArgumentException("sortIndex should less than factorial(the lenght of items)"); } for (int n = 0; n < _valueUsed.Length; n++) { _valueUsed[n] = false; } long factorielLower = MaxIndex; for (int index = 0; index < size; index++) { long factorielBigger = factorielLower; factorielLower = Factorial.GetFactorial(size - index - 1); // factorielBigger / inverseIndex; int resultItemIndex = (int)(sortIndex % factorielBigger / factorielLower); int correctedResultItemIndex = 0; for (; ;) { if (!_valueUsed[correctedResultItemIndex]) { resultItemIndex--; if (resultItemIndex < 0) { break; } } correctedResultItemIndex++; } Result[index] = _sortedValues[correctedResultItemIndex]; _valueUsed[correctedResultItemIndex] = true; } }
// ************************************************************************ public PermutationMixOuelletSaniSinghHuttunen(int[] sortedValues, long indexFirst = -1, long indexLastExclusive = -1) { if (indexFirst == -1) { indexFirst = 0; } if (indexLastExclusive == -1) { indexLastExclusive = Factorial.GetFactorial(sortedValues.Length); } if (indexFirst >= indexLastExclusive) { throw new ArgumentException($"{nameof(indexFirst)} should be less than {nameof(indexLastExclusive)}"); } _indexFirst = indexFirst; _indexLastExclusive = indexLastExclusive; _sortedValues = sortedValues; }