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]