Sort numbers by binary 1's count

J (11)

(\:+/"1@#:)

This is a function that takes a list:

     (\:+/"1@#:) 15342 28943 16375 3944 11746 825 32425 28436 21826 15752 19944
16375 15342 32425 28943 11746 28436 19944 3944 15752 825 21826

If you want to give it a name, it costs one extra character:

     f=:\:+/"1@#:
     f 15342 28943 16375 3944 11746 825 32425 28436 21826 15752 19944
16375 15342 32425 28943 11746 28436 19944 3944 15752 825 21826

Explanation:

  • \:: downwards sort on
  • +/: sum of
  • "1: each row of
  • #:: binary representation

JavaScript, 39

Update: Now shorter than Ruby.

x.sort(q=(x,y)=>!x|-!y||q(x&x-1,y&y-1))

40

x.sort(q=(x,y)=>x&&y?q(x&x-1,y&y-1):x-y)

Explanation:

q is a recursive function. If x or y are 0, it returns x-y (a negative number if x is zero or a positive number if y is zero). Otherwise it removes the lowest bit (x&x-1) from x and y and repeats.

Previous version (42)

x.sort(q=(x,y)=>x^y&&!x-!y+q(x&x-1,y&y-1))

Ruby 41

f=->a{a.sort_by{|n|-n.to_s(2).count(?1)}}

Test:

a = [28943, 825, 11746, 16375, 32425, 19944, 21826, 15752, 15342, 3944, 28436];
f[a]
=> [16375, 15342, 32425, 11746, 28436, 28943, 19944, 15752, 3944, 21826, 825]