4

I want to sort (or sortby) the list. List contains uninitialized variable m and I can assume that m is a Natural number that is much larger then any constant.

Example input:

a = {-116*m, 0, 3 - 11*m, 1 - m, -20*m - 7, -m}

Example output:

{-116*m, -20*m - 7, 3 - 11*m, -m, 1 - m, 0}

My effort:

MAGICNUMBER = 1000000;
Sort[a, (#1 /. m -> MAGICNUMBER) < (#2 /. m -> MAGICNUMBER) &]
J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
Margus
  • 1,987
  • 2
  • 15
  • 19

2 Answers2

5

Your own method seems fairly effective but it can be simplified:

a = {-116*m, 0, 3 - 11*m, 1 - m, -20*m - 7, -m};

SortBy[a, # /. m -> 1`*^12 &]
{-116 m, -7 - 20 m, 3 - 11 m, -m, 1 - m, 0}
a[[ Ordering[a /. m -> 1`*^12] ]]
{-116 m, -7 - 20 m, 3 - 11 m, -m, 1 - m, 0}

These methods will also perform much better than your use of Sort because the default sort algorithm is used rather than custom pairwise ordering.

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
3

For your example input, which happens to be a list with elements in which m appears up to linearly, you can simply do this:

lst = {-116*m, 0, 3 - 11*m, 1 - m, -20*m - 7, -m};
lst[[Ordering[D[lst, m]]]]
(*{-116 m, -7 - 20 m, 3 - 11 m, 1 - m, -m, 0}*)

which basically gets rid of each term that does not contain m, then orders the rest according to the coefficient of m.

If you have things like m^2 though this needs a bit more work.

acl
  • 19,834
  • 3
  • 66
  • 91
  • 'm' appears linearly, therefore it is possible to take derivative. However would that not mean that constant elements would be in random order? – Margus Oct 17 '12 at 00:06
  • @Margus yes that's true, constant elements will remain in the order they are. – acl Oct 17 '12 at 00:08
  • Well, then Sort[lst][[Ordering[D[Sort[lst], m]]]] would work. – Margus Oct 17 '12 at 00:18
  • Yes that's much better than what I was coming up with. Is it OK if I add it to the answer (with credit)? – acl Oct 17 '12 at 00:27