Update
Using itertools.permutation
is obviously inefficient in terms of memory and time to search. To resolve that, you could compute the factorial/inverse factorial representation directly using functions such as those described in this answer:
def rank(n, p, q):
if n == 1:
return 0
s = p[n-1]
p[n-1], p[q[n-1]] = p[q[n-1]], p[n-1]
q[s], q[n-1] = q[n-1], q[s]
return s + n * rank(n-1, p, q)
def unrank(n, r, p):
if n > 0:
p[n-1], p[r % n] = p[r % n], p[n-1]
p = unrank(n - 1, r // n, p)
return p
def f(x):
# sort x including indexes
s = sorted(enumerate(x), key=lambda y:y[1])
# extract the indexes to a list
p = [t[0] for t in s]
# find the factorial number of the tuple
q = [0] * len(p)
for i, v in enumerate(p):
q[v] = i
return rank(len(p), p, q)
def g(y, b):
# find the matching permutation
p = unrank(len(y), b, list(range(len(y))))
# zip the permutation with the values
z = list(zip(y, p))
# sort by the order
s = sorted(z, key=lambda y:y[1])
# and return the values
return [t[0] for t in s]
x = [3,56,43,96,23]
print(x)
b = f(x)
print(b)
y = sorted(x)
print(y)
o = g(y, b)
print(o)
Output:
[3, 56, 43, 96, 23]
108
[3, 23, 43, 56, 96]
[3, 56, 43, 96, 23]
Original answer
You could solve this problem using itertools.permutations
to figure out all of the permutations of len(x)
values and returning the index into that list that matches the sorted order of elements. You can then reverse that process in the g
function, finding the permutation that matches the index and re-sorting y
based on that value:
import itertools
def f(x):
# sort x including indexes
s = sorted(enumerate(x), key=lambda y:y[1])
# extract the indexes to a tuple
i = tuple(t[0] for t in s)
# find all the permutations of length len(x)
p = list(itertools.permutations(range(len(x))))
# find the sorted tuple in the list
return p.index(i)
def g(y, b):
# find all the permutations of length len(y)
p = list(itertools.permutations(range(len(y))))
# zip the permutation with the values
z = list(zip(y, p[b]))
# sort by the order
s = sorted(z, key=lambda y:y[1])
# and return the values
return [t[0] for t in s]
x = [3,56,43,96,23]
print(x)
b = f(x)
print(b)
y = sorted(x)
print(y)
o = g(y, b)
print(o)
Output:
[3, 56, 43, 96, 23]
20
[3, 23, 43, 56, 96]
[3, 56, 43, 96, 23]