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.

How to sort a list, e.g.

RandomInteger[{0, 100}, 50]

that the Maximum is in the center and all other elements are placed symetrically in descending order around the center?

share|improve this question

3 Answers 3

up vote 4 down vote accepted

One way:

SeedRandom[1];

#[[1 ;; ;; 2]] ~Join~ Reverse[#[[2 ;; ;; 2]]] &@
 Sort[RandomInteger[{0, 100}, 50]]
(*
  {0, 3, 4, 10, 15, 18, 24, 26, 29, 30, 38, 43, 44, 47, 54, 65, 68, 68, \
  70, 74, 76, 83, 86, 93, 100, 100, 97, 90, 86, 80, 75, 73, 69, 68, 67, \
  56, 48, 45, 44, 43, 33, 30, 28, 25, 23, 17, 14, 6, 4, 1}
*)

Edit: Or, following @Mr.Wizard's suggestion,

#[[1 ;; ;; 2]] ~Join~ #[[Floor[Length[#], 2] ;; 1 ;; -2]] &@
 Sort[RandomInteger[{0, 100}, 50]]
share|improve this answer
2  
Both shorter and faster: #[[;; ;; 2]] ~Join~ #[[-2 ;; 1 ;; -2]] & –  Mr.Wizard Jul 20 at 15:16
    
@Mr.Wizard I guess I never thought about spanning backwards -- Thanks! –  Michael E2 Jul 20 at 15:18
    
Yeah, it's a nice trick for reversing, but I think I got the spec wrong the first time, now corrected. Check it, will you? –  Mr.Wizard Jul 20 at 15:19
1  
@Mr.Wizard Actually, as I started to edit, I think we have to worry whether the length of the list is odd or even. –  Michael E2 Jul 20 at 15:19
1  
@MichaelE2 yes, having to worry about the length being odd or even makes things a lot uglier –  acl Jul 20 at 15:26

For practice we could write the same thing as in Michael E2's answer with Range and Extract:

symSort[list_] := Module[
  {l = Length@list},
  Extract[Sort@list, List /@ Join @@ Range[{1, Floor[l, 2]}, {l, 1}, {2, -2}]]
  ]

Example:

SeedRandom[1];
symSort[RandomInteger[{0, 100}, 50]]

(* {0,3,4,10,15,18,24,26,29,30,38,43,44,47,54,65,68,68,
70,74,76,83,86,93,100,100,97,90,86,80,75,73,69,68,67,56,48,45,
44,43,33,30,28,25,23,17,14,6,4,1} *)

For lists with an even number of items we could also do

symSort[list_] := Join[First@#, Reverse@Last@#] &@Transpose@Partition[Sort@list, 2]
share|improve this answer

Although this isn't quite as fast as Michael's revised method using negative stepping for reversal I find the following satisfyingly short and clean:

Join[#, Reverse @ #][[;; ;; 2]] &

Both methods are still very fast so I'd personally use this one. :-)

share|improve this answer
    
It takes a little thought to see that it is always correct, but it's quite clever and clean, as you say. I believe it uses twice as much memory, but that's probably not much of a practical limitation. +1 –  Michael E2 Jul 21 at 13:24

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.