Reputation: 129
Suppose you have a sequence of numbers, e.g., {1, 2, 3, 4, 5). from which you want all the permutations without repetition, choosing two elements.
Thus, {1,2}, {1,3}, {1,4}, {1,5}, {2,1}, {2,3}, {2,4} ...
Given an index of the permutation number, e.g., the 6th permutation, is there some easy approach to calculate what that permutation (here {2,4} using zero indexing) looks like?
I see approaches for combinations like: https://math.stackexchange.com/questions/1368526/fast-way-to-get-a-combination-given-its-position-in-reverse-lexicographic-or
I am looking for something similar for my problem. I am using C++.
I have looked at Gray Codes, Lermer Codes, Combinadics, Factoradics, etc. but none of these seem quite right.
Thanks for any help.
Upvotes: 1
Views: 558
Reputation: 54791
If you imagine the pairs filling a grid, wrapping to a new row each time the first number has to change. There will be sequence.length-1
columns.
{1,2}, {1,3}, {1,4}, {1,5},
{2,1}, {2,3}, {2,4}, {2,5},
{3,1}, {3,2}, {3,4}, {3,5},
{4,1}, {4,2}, {4,3}, {4,5},
{5,1}, {5,2}, {5,3}, {5,4},
Find the row and column of the permutation number and then look up the values from the sequence.
val s // sequence
val p // 0 based permutation number
val row = p / (s.length-1) // integer divide (round down)
val col = p % (s.length-1) // remainder
if (col >= row) {
col = col + 1 // to prevent repeat
}
val pair = { s[row], s[col] }
Example:
val s = {1, 2, 3, 4, 5} //sequence
val p = 6
row = 1 (6 / 4 rounded down)
col = 2 (remainer of 6 / 4)
col -> 3 increase as larger than or equal to first index
val pair = { 2, 4 }
Upvotes: 2