2

This question may have a simple answer, but I can't find it anywhere in the documentation. I'm trying to find a function that tells me whether a list is a permutation of another list. So the function should behave like this:

TestPermutation[{1, 2, 3, 4}, {1, 3, 2, 4}] (* Should return True *)

TestPermutation[{1, 2, 3, 4}, {1, 1, 2, 4}] (* Should return False *)

What sort of works is to use FindPermutation[list1, list2], and then catch the error that says e.g.:

FindPermutation::norel: Expressions {1,2,3} and {2,1,2} cannot be related by a permutation. >>

But that isn't a very nice solution. Is there a neat way do do this?

Jelle
  • 281
  • 2
  • 8

3 Answers3

5

so this doesn't sit unanswered..

 testPermutation[ list1_List , list2_List ] := Sort[list1] == Sort[list2] ; 
 testPermutation[{1, 2, 3, 4}, {1, 3, 2, 4}]
 testPermutation[{1, 2, 3, 4}, {1, 1, 2, 4}]

True

False

or generalized to multiple lists:

 testPermutation[ list__List  ] := Equal @@ Sort /@ List@list
 testPermutation[{1, 2, 3, 4}, {1, 3, 2, 4}, {1, 2, 4, 3}]
 testPermutation @@ Permutations[{1, 2, 3, 4}]

True

True

george2079
  • 38,913
  • 1
  • 43
  • 110
2

Not so nice as george2079's answer but maybe faster with large matrices (avoids sorting):

testPermutation[m_] := 
 Length@Flatten@
      Table[Position[m[[i]], m[[1, j]]], {i, 2, Length@m}, {j, 1, 
        Length@First@m}] == (Times @@ # - Last@#&@Dimensions@m)

testPermutation@{{1, 2, 3, 4}, {1, 3, 2, 4}, {1, 2, 4, 3}}

True

testPermutation@{{1, 2, 3, 4}, {1, 3, 2, 4}, {5, 2, 4, 3}}

False

eldo
  • 67,911
  • 5
  • 60
  • 168
1

Another simple solution could be based on Cycles[]. The existence of duplicates is also tested.

testPermutation[l1_List, l2_List] :=
 With[{
   len1 = Length@l1,
   lu1 = CountDistinct@l1,
   lu2 = CountDistinct@l2}, 
  And[lu1 == lu2 == len1, Cycles[{l1}] == Cycles[{l2}]]]
Soldalma
  • 1,289
  • 1
  • 9
  • 17