6
$\begingroup$

I am new to using Mathematica and I can not find a solution to what I am wanting to do.

I want to take a list such as:

x = {1,2,3,4,5,6,7,8}

and a second list (permutation):

perm = {4,1,6,2,7,3,8,5}

and get a result to where the permutation is applied to x. So the return would be 2,4,6,1,8,3,5,7.

My goal is a function like permutationEncrypt[x_, permutation_] := return x with the permutation applied to it

I know I can sort a list, but how would I accomplish what I am wanting to do?

$\endgroup$
3
  • $\begingroup$ Welcome to Mathematica.SE! I suggest that: 1) You take the introductory Tour now! 2) When you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge. Also, please remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign! 3) As you receive help, try to give it too, by answering questions in your area of expertise. $\endgroup$
    – bbgodfrey
    Commented Feb 3, 2015 at 2:36
  • $\begingroup$ Please add code that you have attempted to use to solve this problem. $\endgroup$
    – bbgodfrey
    Commented Feb 3, 2015 at 2:37
  • $\begingroup$ Related: (2323), (56848) $\endgroup$
    – Mr.Wizard
    Commented Feb 3, 2015 at 17:34

5 Answers 5

7
$\begingroup$

A simple way is:

y = x; y[[perm]] = x; y
(* {2, 4, 6, 1, 8, 3, 5, 7} *)
$\endgroup$
6
$\begingroup$

Permute gives what you expect to get from permutationEncrypt:

Permute[x, perm]
(* {2, 4, 6, 1, 8, 3, 5, 7} *)

You can also use Ordering:

peF[x_, p_] := x[[Ordering @ p]]

peF[x, perm]
(* {2, 4, 6, 1, 8, 3, 5, 7} *)

Or, ReplaceAll:

peF2 = # /. Thread[#2 -> #] &;

peF2[x, perm]
(* {2, 4, 6, 1, 8, 3, 5, 7} *)
$\endgroup$
1
  • $\begingroup$ I think that last one should be Range@Length@x /. $\endgroup$
    – Mr.Wizard
    Commented Feb 3, 2015 at 17:38
3
$\begingroup$

Timings for the methods posted:

Needs["GeneralUtilities`"]

f1[{x_, perm_}] := Permute[x, perm]
f2[{x_, perm_}] := x[[Ordering @ perm]]
f3[{x_, perm_}] := Table[x[[Position[perm, i][[1, 1]]]], {i, Length[x]}]
f4[{x_, perm_}] := Module[{y = x}, y[[perm]] = x; y]

BenchmarkPlot[
 {f1, f2, f3, f4},
 {RandomInteger[99, #], RandomSample@Range@#} &,
 TimeConstraint -> 15
]

enter image description here

So it seems Simon's code beats the built-in function. :^)

$\endgroup$
3
$\begingroup$

Using PositionIndex:

pi = PositionIndex@perm;
pi[#] & /@ x // Flatten

or

lut = PositionIndex@perm // KeyValueMap[#1 -> First@#2 &]
Lookup[lut, x]

{2, 4, 6, 1, 8, 3, 5, 7}

$\endgroup$
2
$\begingroup$

Although not as elegant, this also works.

Table[x[[Position[perm, i][[1, 1]]]], {i, Length[x]}]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.