4
$\begingroup$

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?

$\endgroup$
0

3 Answers 3

5
$\begingroup$

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]]
$\endgroup$
8
  • 2
    $\begingroup$ Both shorter and faster: #[[;; ;; 2]] ~Join~ #[[-2 ;; 1 ;; -2]] & $\endgroup$
    – Mr.Wizard
    Jul 20, 2014 at 15:16
  • $\begingroup$ @Mr.Wizard I guess I never thought about spanning backwards -- Thanks! $\endgroup$
    – Michael E2
    Jul 20, 2014 at 15:18
  • $\begingroup$ 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? $\endgroup$
    – Mr.Wizard
    Jul 20, 2014 at 15:19
  • 1
    $\begingroup$ @Mr.Wizard Actually, as I started to edit, I think we have to worry whether the length of the list is odd or even. $\endgroup$
    – Michael E2
    Jul 20, 2014 at 15:19
  • 1
    $\begingroup$ @MichaelE2 yes, having to worry about the length being odd or even makes things a lot uglier $\endgroup$
    – acl
    Jul 20, 2014 at 15:26
2
$\begingroup$

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]
$\endgroup$
2
$\begingroup$

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. :-)

$\endgroup$
1
  • $\begingroup$ 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 $\endgroup$
    – Michael E2
    Jul 21, 2014 at 13:24

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.