Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have 4 different items {1, 2, 3, 4}. I want to obtain all possible pairs of two of the items. I have written:

n = 4;
x1 = Tuples[Range@n, n];

Cases[x1, {a_, a_, b_, b_} /; a != b]

gives the desired result:

{{1, 1, 2, 2}, {1, 1, 3, 3}, {1, 1, 4, 4}, {2, 2, 1, 1}, {2, 2, 3, 3}, {2, 2, 4, 4}, {3, 3, 1, 1}, {3, 3, 2, 2}, {3, 3, 4, 4}, {4, 4, 1, 1}, {4, 4, 2, 2}, {4, 4, 3, 3}}

Now I choose

n = 6;
x2 = Tuples[Range@n, n];

Cases[x2, {a_, a_, b_, b_, c_, c_} /; a != b && a != c && b != c];
% // Short

{{1,1,2,2,3,3},{1,1,2,2,4,4},<<116>>,{6,6,5,5,3,3},{6,6,5,5,4,4}}

again gives the desired result.

How would you automate this (for even n)?

Are there better alternatives?

share|improve this question
    
@Szabolcs Well almost, but not quite. For Subsets you'll need to generate additional permutations in order to get the desired output, and for Tuples you'll need to throw away cases of repeated pairs. –  Teake Nutma Jul 16 at 17:49
    
@Öska Thanks for the edit and Short –  eldo Jul 16 at 19:47

2 Answers 2

up vote 4 down vote accepted

This is another approach:

pairRiffle[n_?EvenQ] := Riffle[#, #] & /@ (Permutations[Range@n, {n/2}])

pairRiffle[4]
(* {{1, 1, 2, 2}, {1, 1, 3, 3}, {1, 1, 4, 4}, {2, 2, 1, 1}, {2, 2, 3, 
  3}, {2, 2, 4, 4}, {3, 3, 1, 1}, {3, 3, 2, 2}, {3, 3, 4, 4}, {4, 4, 
  1, 1}, {4, 4, 2, 2}, {4, 4, 3, 3}} *)

Edit: in fact I could do without the Riffle and just use the transformation rule in @Teake Nutma's answer

pairHybrid[n_?EvenQ] :=  Permutations[Range@n, {n/2}] /. x_Integer -> Sequence[x, x]

pairHybrid[10] == Sort@AllPairs[10]
(* True *)
pairRiffle[10] == Sort@AllPairs[10]
(* True *)
share|improve this answer
1  
+1 for the second argument of Permutations. –  Teake Nutma Jul 16 at 19:14
    
Thanks! +1 to you too for the inspiration. –  seismatica Jul 16 at 19:16
    
@seismatica +1 A funny development :) –  eldo Jul 16 at 19:18
    
Nice use of Riffle! That's my favorite way to double elements. –  Mr.Wizard Jul 22 at 2:54

This should do the job:

AllPairs[n_?EvenQ] := 
   Flatten[Permutations /@ Subsets[Range[n], {n/2}], 1] /. x_Integer :> Sequence[x, x]

AllPairs[4]
{
  {1, 1, 2, 2}, {2, 2, 1, 1}, {1, 1, 3, 3}, {3, 3, 1, 1}, 
  {1, 1, 4, 4}, {4, 4, 1, 1}, {2, 2, 3, 3}, {3, 3, 2, 2}, 
  {2, 2, 4, 4}, {4, 4, 2, 2}, {3, 3, 4, 4}, {4, 4, 3, 3}
}
share|improve this answer
    
+1 exactly what I was looking for –  eldo Jul 16 at 17:52

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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