Sortir angka berdasarkan jumlah biner 1

35

Tujuan

Tulis sebuah fungsi atau program, urutkan array bilangan bulat dalam urutan menurun dengan jumlah 1 yang ada dalam representasi biner mereka. Tidak diperlukan kondisi penyortiran sekunder.

Contoh daftar yang diurutkan

(menggunakan bilangan bulat 16-bit)

  Dec                Bin        1's
16375   0011111111110111        13
15342   0011101111101110        11
32425   0111111010101001        10
11746   0010110111100010         8
28436   0000110111110100         8
19944   0100110111101000         8
28943   0000011100011111         8
 3944   0000011111101000         7
15752   0011110110001000         7
  825   0000000011111001         6
21826   0101010101000010         6

Memasukkan

Array bilangan bulat 32-bit.

Keluaran

Array bilangan bulat yang sama diurutkan seperti yang dijelaskan.

Mencetak gol

Ini adalah kode golf untuk jumlah byte terkecil yang akan dipilih dalam waktu satu minggu.

Makanan Tangan
sumber
2
Anda tidak menyebutkan secara eksplisit, tetapi apakah harus dalam urutan menurun?
Nick T
3
Anda benar, saya melewatkan itu. Semua orang telah pergi dengan turun, jadi kami akan tetap dengan itu.
Hand-E-Food
Saya pikir angka terakhir (21826) telah dikonversi salah. menurut kalkulator Windows saya, ini 0101 0101 0100 0010, bukan 0010 1010 1100 0010.
Nzall
Terima kasih atas koreksi itu. Itu aneh tentang 21826 karena saya menggunakan Excel untuk mengubah angka menjadi biner. Saya bertanya-tanya tentang sisanya sekarang.
Hand-E-Food
Solusi menggunakan instruksi assembly dan popcount?
eiennohito

Jawaban:

27

J (11)

(\:+/"1@#:)

Ini adalah fungsi yang mengambil daftar:

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

Jika Anda ingin memberi nama, biayanya satu karakter tambahan:

     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

Penjelasan:

  • \:: ke bawah semacam
  • +/: jumlah dari
  • "1: setiap baris
  • #:: representasi biner
marinus
sumber
5
@ ak82 itu versi ASCII dari APL
John Dvorak
3
@JanDvorak semacam; ada beberapa perubahan: jsoftware.com/papers/j4apl.htm (lihat bagian Bahasa).
James Wood
3
Ada juga \:1#.#:yang menyimpan beberapa byte.
mil
17

JavaScript, 39

Pembaruan: Sekarang lebih pendek dari 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)

Penjelasan:

q adalah fungsi rekursif. Jika x atau y adalah 0, ia mengembalikan x-y(angka negatif jika x adalah nol atau angka positif jika y adalah nol). Kalau tidak, ia akan menghapus bit terendah ( x&x-1) dari x dan y dan berulang.

Versi sebelumnya (42)

x.sort(q=(x,y)=>x^y&&!x-!y+q(x&x-1,y&y-1))
salinan
sumber
Ini sangat pintar! Saya masih mencoba membungkus pikiran saya di sekitarnya.
mowwwalker
Bukankah seharusnya ~ybekerja -!y?
Sikat gigi
@toothbrush Kondisi akhir adalah x atau y adalah 0, dalam hal ini ekspresi !x|-!ymenjadi tidak nol. ~tidak cocok karena ini bukan nol untuk banyak input (termasuk nol)
salin
Adakah yang bisa membantu saya jika diperlukan penyortiran sekunder ?
Manubhargav
15

Ruby 41

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

Uji:

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]
daniero
sumber
2
Sederhana. Bisa dimengerti Pendek. Kudos untuk solusi ini.
Pierre Arlaud
8

Python 3 (44):

def f(l):l.sort(lambda n:-bin(n).count('1'))
Blender
sumber
8

Common Lisp, 35

logcountmengembalikan jumlah 'on'-bit dalam suatu angka. Untuk daftar l, kami memiliki:

(sort l '> :key 'logcount)
CL-USER> (sort (list 16375 15342 32425 11746 28436 19944 28943 3944 15752 825 21826) '> :key 'logcount)
;=> (16375 15342 32425 11746 28436 19944 28943 3944 15752 825 21826)

Sebagai fungsi mandiri, dan berdasarkan apa byte akan digunakan:

(lambda(l)(sort l'> :key'logcount))
Joshua Taylor
sumber
7

Python 3, 90 77 72 67 karakter.

Solusi kami mengambil input dari baris perintah, dan mencetak nomor dalam urutan menurun (67 karakter), atau naik (66).

Urutan menurun

print(sorted(input().split(),key=lambda x:-bin(int(x)).count("1"))) # 67

Terima kasih kepada @daniero , untuk saran menggunakan minus pada hitungan 1 untuk membalikkannya, daripada menggunakan slice untuk membalikkan array pada akhirnya! Ini secara efektif menyimpan 5 karakter.

Hanya demi mempostingnya, versi urutan naik (yang pertama kali kami buat) akan mengurangi satu karakter.

Urutan naik :

print(sorted(input().split(),key=lambda x:bin(int(x)).count("1"))) # 66

Terima kasih kepada @ Bakuriu untuk saran kunci = lambda x… . ; D

Jetlef
sumber
Jadi 0akan selalu menjadi bagian dari output Anda kemudian; Itu tidak benar.
daniero
Saya tidak melihat apa pun dalam pertanyaan yang melarang saya memasukkan nilai.
Jetlef
Saya lakukan: "Array bilangan bulat yang sama diurutkan seperti dijelaskan." ;) Selain itu, mengapa tidak menggunakan raw_input()dan menjatuhkan beberapa karakter saja?
daniero
1
@daniero memperbaikinya. Beralih ke Python 3 (jawaban Python 2 sudah ada, harus kreatif!) Memungkinkan saya menggunakan input () , menyimpan dua karakter (dua harus ditambahkan karena tanda kurung diperlukan oleh print () ).
Jetlef
Anda bisa menjatuhkan bagian []dalamnya sorted. Juga output dari program ini adalah jumlah 1s dalam angka-angka dalam input diurutkan, tetapi Anda harus menampilkan nomor yang Anda terima dalam input, diurutkan menggunakan jumlah 1s. Sesuatu seperti: print(sorted(input().split(), key=lambda x:bin(int(x)).count('1')))akan benar.
Bakuriu
7

JavaScript [76 byte]

a.sort(function(x,y){r='..toString(2).split(1).length';return eval(y+r+-x+r)})

di mana ainput array angka.

Uji:

[28943,825,11746,16375,32425,19944,21826,15752,15342,3944,28436].sort(function(x, y) {
    r = '..toString(2).split(1).length';
    return eval(y + r + -x + r);
});

[16375, 15342, 32425, 19944, 11746, 28943, 28436, 15752, 3944, 21826, 825]
Penglihatan
sumber
Bisakah Anda memberi tahu cara ..kerjanya? Pemahaman saya adalah bahwa jika x = 5kemudian eval(x + r)menjadi eval(5..toString(2).match(/1/g).length)yang saya kira tidak valid. Terima kasih.
Gaurang Tandon
1
@ GaurangTandon Tidak. Seperti yang Anda tahu, di JS semuanya kecuali literal adalah objek. Dan angka. Jadi secara teoritis (dan praktis) Anda bisa mendapatkan properti atau memanggil metode non-literal melalui notasi titik, seperti yang Anda lakukan 'string'.lengthatau [1,2,3].pop(). Dalam hal angka Anda dapat melakukan hal yang sama tetapi Anda harus ingat bahwa setelah satu titik parser akan mencari bagian fraksional dari angka yang mengharapkan nilai float (seperti dalam 123.45). Jika Anda menggunakan integer Anda harus "kirim" parser bahwa sebagian pecahan kosong, menetapkan dot ekstra sebelum menangani properti: 123..method().
VisioN
1
Anda dapat menyimpan dua byte dengan melepaskan nol dan memperlakukan sisanya sebagai angka desimal. Ganti match(/1/g).lengthdengan replace(/0/g,"").
DocMax
@Visio Terima kasih! Belajar hal baru.
Gaurang Tandon
1
a.sort(function(x,y){r='..toString(2).match(/1/g).length';return eval(y+r+-x+r)})
l4m2
6

Mathematica 30

SortBy[#,-DigitCount[#,2,1]&]&

Pemakaian:

SortBy[#,-DigitCount[#,2,1]&]&@
                           {19944,11746,15342,21826,825,28943,32425,16375,28436,3944,15752}

{16375, 15342, 32425, 11746, 19944, 28436, 28943, 3944, 15752, 825, 21826}

Belisarius
sumber
6

k [15 Karakter]

{x@|<+/'0b\:'x}

Contoh 1

{x@|<+/'0b\:'x}19944, 11746, 15342, 21826, 825, 28943, 32425, 16375, 28436, 3944, 15752

16375 15342 32425 28436 28943 11746 19944 15752 3944 825 21826

Contoh 2 (semua angka 2 ^ n -1)

{x@|<{+/0b\:x}'x}3 7 15 31 63 127

127 63 31 15 7 3
nyi
sumber
5

Mathematica 39

IntegerDigits[#,2] mengonversi nomor basis 10 ke daftar 1 dan 0.

Tr menjumlahkan digit.

f@n_:=SortBy[n,-Tr@IntegerDigits[#,2]&]

Kasus cobaan

f[{19944, 11746, 15342, 21826, 825, 28943, 32425, 16375, 28436, 3944, 15752}]

{16375, 15342, 32425, 11746, 19944, 28436, 28943, 3944, 15752, 825, 21826}

DavidC
sumber
Saya menyukai penggunaan Tr [] dalam kode golf.
Michael Stern
5

Java 8 - 87/113 81/111 60/80 60/74/48 karakter

Ini bukan program java yang lengkap, ini hanya sebuah fungsi (metode, tepatnya).

Diasumsikan bahwa java.util.Listdan java.lang.Long.bitCountdiimpor, dan memiliki 60 karakter:

void s(List<Long>a){a.sort((x,y)->bitCount(x)-bitCount(y));}

Jika tidak ada barang pra-impor diizinkan, ini dia dengan 74 karakter:

void s(java.util.List<Long>a){a.sort((x,y)->x.bitCount(x)-x.bitCount(y));}

Tambahkan lebih dari 7 karakter jika diperlukan static.

[4 tahun kemudian] Atau jika Anda mau, itu bisa berupa lambda (terima kasih @KevinCruijssen untuk sarannya), dengan 48 byte:

a->{a.sort((x,y)->x.bitCount(x)-x.bitCount(y));}
Victor Stafusa
sumber
Ada alasan mengapa Anda tidak bisa melakukannya Integer.bitCount(x)<Integer.bitCount(y)?-1:1;? Apakah Anda memerlukan -1,0,1perilaku itu?
Justin
Juga, apakah mungkin untuk mengganti <Integer>dengan ruang?
Justin
Anda juga dapat menggunakan Long, yang menghemat ruang :)
RobAu
Juga a.sort((x,y)->Long.bitCount(x)-Long.bitCount(y));
RobAu
1
@KevinCruijssen Terima kasih. Saya sangat terbiasa bahwa menggunakan contoh variabel untuk memanggil metode statis adalah praktik buruk yang saya pernah lupa bahwa kompiler menerimanya.
Victor Stafusa
4

Python 2.x - 65 karakter (byte)

print sorted(input(),key=lambda x:-sum(int(d)for d in bin(x)[2:]))

Itu sebenarnya 66 karakter, 65 jika kita membuatnya berfungsi (maka Anda perlu sesuatu untuk memanggilnya yang ingin ditampilkan).

f=lambda a:sorted(a,key=lambda x:-sum(int(d)for d in bin(x)[2:]))

Demo di Bash / CMD:

echo [16, 10, 7, 255, 65536, 5] | python -c "print sorted(input(),key=lambda x:-sum(int(d)for d in bin(x)[2:]))"
Nick T
sumber
Anda dapat mengubah sum(int(d)for d in bin(x)[2:])kesum(map(int,bin(x)[2:]))
Elisha
1
atau bahkan:print sorted(input(),key=lambda x:-bin(x).count('1'))
Elisa
4

Matlab, 34

Masukkan 'a'

[~,i]=sort(-sum(dec2bin(a)'));a(i)

Berfungsi untuk nomor non-negatif.

fraktal
sumber
4

C - 85 byte (108 106 byte)

Versi portabel pada GCC / Dentang / di mana pun __builtin_popcounttersedia (106 byte):

#define p-__builtin_popcount(
c(int*a,int*b){return p*b)-p*a);}
void s(int*n,int l){qsort(n,l,sizeof l,c);}

Versi MSVC-satunya ultra-kondensasi, non-portabel, hampir tidak berfungsi (85 byte):

#define p __popcnt
c(int*a,int*b){return p(*b)-p(*a);}
s(int*n,int l){qsort(n,l,4,c);}         /* or 8 as needed */

  • Baris pertama pertama dimasukkan dalam hitungan byte karena #define, yang lain tidak diperlukan.

  • Fungsi untuk menelepon s(array, length)sesuai dengan spesifikasi.

  • Dapat meng-hardcode sizeofdalam versi portabel untuk menyimpan 7 karakter lainnya, seperti beberapa jawaban C lainnya. Saya tidak yakin yang mana yang paling layak dalam hal rasio kegunaan-panjang, Anda memutuskan.

Thomas
sumber
2
sizeof lmenghemat satu byte. Yang jelek #define p-__builtin_popcount(bisa membantu menyelamatkan yang lain.
ugoren
@ugoren Terima kasih atas tipsnya! Yang preprocessor adalah hack seperti itu, saya tidak tahu hal seperti itu mungkin terjadi. Sayangnya itu tidak bekerja di MSVC, tetapi setiap byte penting!
Thomas
4

PowerShell v3, 61 58 53

$args|sort{while($_){if($_-band1){1};$_=$_-shr1}}-des

ScriptBlock untuk Sort-Objectcmdlet mengembalikan array 1 untuk setiap 1 dalam representasi biner dari angka tersebut. Sort-Objectmengurutkan daftar berdasarkan panjang array yang dikembalikan untuk setiap nomor.

Untuk mengeksekusi:

script.ps1 15342 28943 16375 3944 11746 825 32425 28436 21826 15752 19944
Rynant
sumber
ini bekerja. Bagaimana cara kerjanya? Bagaimana keajaibannya. ' datang ke 'berdasarkan panjang array'?
mazzy
'.' mengeksekusi blokir script yang datang setelah itu. Perintah sortir berdasarkan pada output dari scriptblock luar. Saya menyadari sekarang bahwa scriptblock bagian dalam tidak diperlukan. lihat edit
Rynant
$f={berlebihan, while-> for, -band1-> %2, -des-> -ddan trik golf lainnya. Itu sudah jelas. Bisakah Anda menjelaskan cara kerjanya $args|sort{@(1,1,...,1)}? Ini berhasil! Bagaimana cara membandingkan array tanpa eksplisit .Count? di mana membaca tentang itu? Terima kasih!
mazzy
1
@ Mazzy, Anda benar, saya menghapus bit yang berlebihan sekarang. Ini adalah penyortiran default cmdlet Sort-Object. Lihat: help Sort-Object -Parameter propertySaya tidak tahu di mana properti penyortiran default untuk tipe didefinisikan, tetapi untuk array adalah Count atau Panjang.
Rynant
Tebakan yang bagus. Namun $args|sort{while($_){if($_-band1){$_};$_=$_-shr1}}-desmemberikan hasil yang salah. Karena itu tidak Count. Itu sangat menarik. Terima kasih lagi.
mazzy
3

ECMASkrip 6, 61

Asumsikan zadalah input

z.sort((a,b)=>{c=d=e=0;while(++c<32)d+=a>>c&1,e+=b>>c&1},e-d)

Uji data

[28943,825,11746,16375,32425,19944,21826,15752,15342,3944,28436].sort(
    (a,b)=>{
        c=d=e=0;
        while(++c<32)
            d+=a>>c&1,e+=b>>c&1
    },e-d
)

[16375, 15342, 32425, 11746, 19944, 28436, 28943, 15752, 3944, 21826, 825]

Terima kasih, sikat gigi untuk solusi yang lebih singkat.

Danny
sumber
1
Saya baru saja mencoba solusi Anda, tetapi tidak berhasil. Itu tidak mengurutkan angka.
Sikat gigi
@toothbrush woops. Terima kasih sudah menangkap itu, harus bekerja sekarang.
Danny
Kerja bagus! Saya suka itu.
Sikat gigi
1
Hanya 61 byte: z.sort((a,b)=>{c=d=e=0;while(++c<32)d+=a>>c&1,e+=b>>c&1},e-d)(dan terima kasih atas suaranya).
Sikat gigi
1
Solusi saya sekarang sama dengan ukuran Anda!
Sikat gigi
3

R , 132 96 94 88 84 75 73 53 51 byte

-20 Berkat implementasi J.oe -2 Lebih banyak terima kasih kepada Giuseppe

function(x)x[order(colSums(sapply(x,intToBits)<1))]

Posting asli saya:

pryr::f(rev(x[order(sapply(x,function(y)sum(as.double(intToBits(y)))))]))

Cobalah online!

Saya mencoba beberapa metode yang berbeda sebelum saya sampai pada hasil ini.

Metode Matriks: Membuat matriks dua kolom, satu kolom dengan vektor input, salah satu dari jumlah representasi biner, lalu saya urutkan berdasarkan jumlah biner.

function(x){m=matrix(c(x,colSums(sapply(x,function(y){as.integer(intToBits(y))}))),nc=2,nr=length(x));m[order(m[,2],decreasing=T),]}

Non-Matriks: Menyadari bahwa saya dapat membuang fungsi matriks dan sebagai gantinya membuat vektor nilai-nilai biner, menjumlahkannya, memesannya, lalu menggunakan nilai yang diurutkan untuk menyusun ulang vektor input.

function(x){m=colSums(sapply(x,function(y){as.integer(intToBits(y))}));x[order(m,decreasing=T)]}

Perubahan kecil

function(x){m=colSums(sapply(x,function(y)as.double(intToBits(y))));x[order(m,decreasing=T)]}

Lebih Banyak Perubahan Kecil Mengubah seluruh hal menjadi satu baris kode alih-alih dipisahkan oleh tanda titik koma.

function(x)x[order(colSums(sapply(x,function(y)as.double(intToBits(y)))),decreasing=T)]

Metode Sum Alih-alih menambahkan kolom dengan colSumsmatriks biner yang dibuat oleh sapply, saya menambahkan elemen dalam kolom sebelum sapply"selesai."

function(x)x[order(sapply(x,function(y)sum(as.double(intToBits(y)))),decreasing=T)]

Penurunan untuk Rev Aku benar-benar ingin mempersingkat menurun, tetapi R squawks pada saya jika saya mencoba untuk mempersingkat decreasingdalam orderfungsi, yang diperlukan untuk mendapatkan pesanan yang diinginkan sebagai orderdefault untuk meningkat, maka saya teringat revfungsi untuk membalikkan vektor. EUREKA !!! Perubahan terakhir dalam solusi akhir adalah functionuntuk pryr::fmenyelamatkan 2 byte lagi

function(x)rev(x[order(sapply(x,function(y)sum(as.double(intToBits(y)))))])
Sumner18
sumber
1
53 bytes
J.
1
51 byte meningkat pada @ J.Doe golf yang luar biasa!
Giuseppe
2

Haskell, 123C

import Data.List
import Data.Ord
b 0=[]
b n=mod n 2:b(div n 2)
c n=(n,(sum.b)n)
q x=map fst$sortBy(comparing snd)(map c x)

Ini adalah cara pertama yang saya pikirkan untuk menyelesaikan ini, tapi saya yakin ada cara yang lebih baik untuk melakukannya. Juga, jika ada yang tahu tentang cara golf Haskell impor, saya akan sangat tertarik untuk mendengarnya.

Contoh

*Main> q [4,2,15,5,3]
[4,2,5,3,15]
*Main> q [7,0,2]
[0,2,7]

Versi tidak digabungkan (dengan penjelasan)

import Data.List
import Data.Ord

-- Converts an integer into a list of its bits
binary 0 = []
binary n = mod n 2 : binary (div n 2)

-- Creates a tuple where the first element is the number and the second element
-- is the sum of its bits.
createTuple n = (n, (sum.binary) n)

-- 1) Turns the list x into tuples
-- 2) Sorts the list of tuples by its second element (bit sum)
-- 3) Pulls the original number out of each tuple
question x = map fst $ sortBy (comparing snd) (map createTuple x)
danmcardle
sumber
itu akan membantu untuk menggunakan notasi infix untuk mod, n`mod`2? Ia memiliki prioritas yang sama dengan perkalian dan pembagian.
John Dvorak
Itu tidak akan terlalu membantu untuk alasan bermain golf sejauh yang saya bisa lihat. Saya akan kehilangan dua spasi, tetapi mendapatkan dua backticks, kan?
danmcardle
impor Data.List; impor Data.Ord; impor Data.Bits; q = sortBy (membandingkan popCount) - 80C - atau menggunakan pendekatan Anda, impor Data.List; impor Data.Ord; b 0 = 0; bn = (mod n 2) + b (div n 2); q = sortBy (membandingkan b) - 86C
bazzargh
Saya mencoba menghindari impor sepenuhnya, yang terbaik yang dapat saya kelola adalah 87C dengan bermain golf quicksort: b 0 = 0; bn = mod n 2 + b (div n 2); q [] = []; q (a: c) = f ( (ba>). b) c ++ a: f ((ba <=). b) c; f = (q.) filter
bazzargh
2

CoffeeScript (94)

Kode yang dapat dibaca (212):

sort_by_ones_count = (numbers) ->
  numbers.sort (a, b) ->
    a1 = a.toString(2).match(/1/g).length
    b1 = b.toString(2).match(/1/g).length
    if a1 == b1
      0
    else if a1 > b1
      1
    else
      -1

console.log sort_by_ones_count [825, 3944, 11746, 15342, 15752, 16375, 19944, 21826, 28436, 28943, 32425]

Dioptimalkan (213):

count_ones = (number) -> number.toString(2).match(/1/g).length
sort_by_ones_count = (numbers) -> numbers.sort (a, b) ->
  a1 = count_ones(a)
  b1 = count_ones(b)
  if a1 == b1 then 0 else if a1 > b1 then 1 else -1

Mengaburkan (147):

c = (n) -> n.toString(2).match(/1/g).length
s = (n) -> n.sort (a, b) ->
  a1 = c(a)
  b1 = c(b)
  if a1 == b1 then 0 else if a1 > b1 then 1 else -1

Operator ternary terlalu panjang (129):

c = (n) -> n.toString(2).match(/1/g).length
s = (n) -> n.sort (a, b) ->
  a1 = c(a)
  b1 = c(b)
  (0+(a1!=b1))*(-1)**(0+(a1>=b1))

Terlalu lama, hentikan casting (121):

c = (n) -> n.toString(2).match(/1/g).length
s = (n) -> n.sort (a, b) ->
  a1 = c(a)
  b1 = c(b)
  (-1)**(a1>=b1)*(a1!=b1)

Final (94):

c=(n)->n.toString(2).match(/1/g).length
s=(n)->n.sort((a, b)->(-1)**(c(a)>=c(b))*(c(a)!=c(b)))
Aaron J
sumber
2

Smalltalk (Smalltalk / X), 36 (atau mungkin 24)

masukan dalam; secara destruktif memilah:

a sort:[:a :b|a bitCount>b bitCount]

versi fungsional: mengembalikan array yang diurutkan baru:

a sorted:[:a :b|a bitCount>b bitCount]

bahkan ada varian yang lebih pendek (lewat nama atau fungsi sebagai argumen) dalam 24 karakter. Tapi (menghela napas) itu akan mengurutkan tertinggi terakhir. Seperti yang saya pahami, ini tidak diminta, jadi saya tidak menganggapnya sebagai skor golf:

a sortBySelector:#bitCount
blabla999
sumber
2

PHP 5.4+ 131

Saya bahkan tidak tahu mengapa saya repot-repot dengan PHP, dalam hal ini:

<?unset($argv[0]);usort($argv,function($a,$b){return strcmp(strtr(decbin($b),[0=>'']),strtr(decbin($a),[0=>'']));});print_r($argv);

Pemakaian:

> php -f sortbybinaryones.php 15342 28943 16375 3944 11746 825 32425 28436 21826 15752 19944
Array
(
    [0] => 16375
    [1] => 15342
    [2] => 32425
    [3] => 28436
    [4] => 19944
    [5] => 11746
    [6] => 28943
    [7] => 3944
    [8] => 15752
    [9] => 825
    [10] => 21826
)
Dabbler yang Layak
sumber
well, seseorang harus repot dengan PHP
Einacio
2

Scala, 58

def c(l:List[Int])=l.sortBy(-_.toBinaryString.count(_>48))
ValarDohaeris
sumber
2

DFSORT (produk penyortiran Mainframe IBM) 288 (setiap baris sumber adalah 72 karakter, harus memiliki ruang di posisi satu)

 INREC IFTHEN=(WHEN=INIT,BUILD=(1,2,1,2,TRAN=BIT)), 
       IFTHEN=(WHEN=INIT,FINDREP=(STARTPOS=3,INOUT=(C'0',C'')))
 SORT FIELDS=(3,16,CH,D) 
 OUTREC BUILD=(1,2)

Hanya untuk bersenang-senang, dan tanpa matematika.

Mengambil file (dapat dieksekusi dari program yang menggunakan "array") dengan integer. Sebelum mengurutkan, ia menerjemahkan bilangan bulat ke bit (dalam bidang 16 karakter). Kemudian mengubah 0s dalam bit menjadi nol. SORT Turun pada hasil bit yang diubah. Membuat file yang diurutkan hanya dengan integer.

Bill Woodger
sumber
2

C

void main()
{
 int a[]={7,6,15,16};
 int b,i,n=0;
 for(i=0;i<4;i++)
 {  for(b=0,n=0;b<=sizeof(int);b++)
      (a[i]&(1<<b))?n++:n;   
    a[i]=n;
 }
 for (i = 1; i < 4; i++) 
  {   int tmp = a[i];
      for (n = i; n >= 1 && tmp < a[n-1]; n--)
         a[n] = a[n-1];
      a[n] = tmp;
  }    
}
Venkatesh K
sumber
4
Karena ini adalah kompetisi kode golf, Anda harus mencoba mempersingkat kode Anda.
Timtech
2

C #, 88 89

int[] b(int[] a){return a.OrderBy(i=>-Convert.ToString(i,2).Count(c=>c=='1')).ToArray();}

Edit: urutan menurun menambahkan karakter.

Rik
sumber
2

Javascript 84

Terinspirasi oleh jawaban javascript lainnya, tetapi tanpa eval dan regex.

var r=(x)=>(+x).toString(2).split('').reduce((p,c)=>p+ +c)
[28943,825,11746,16375,32425,19944,21826,15752,15342,3944,28436].sort((x,y)=>r(x)-r(y));
Vittore
sumber
Pertanyaannya adalah golf kode, coba 'golf' kode Anda: hapus spasi yang tidak perlu dan coba buat kode Anda sekecil mungkin. Juga, sertakan jumlah karakter dalam jawaban Anda.
ProgramFOX
2

Javascript (82)

a.sort(function(b,c){q=0;while(b|c){b%2?c%2?0:q++:c%2?q--:0;b>>=1;c>>=1}return q})
mowwwalker
sumber
2

Catatan tambahan, 126

Karena daftar nilai yang digunakan untuk mengurutkan dikenal sebelumnya dan sangat terbatas (32), tugas ini dapat dengan mudah dilakukan bahkan jika tidak ada bawaan untuk menyortir, dengan memilih nilai yang cocok untuk 1..32. (Apakah itu O (32n)? Mungkin).

Prosedur mengharapkan array pada stack dan mengembalikan array yang 'diurutkan'.

/sort_by_bit_count {
    [ exch
    32 -1 1 {
        1 index
        {
            dup 2 32 string cvrs
            0 exch
            {48 sub add} forall
            2 index eq 
            {3 1 roll} {pop} ifelse
        } forall
        pop
    } for
    pop ]
} def

Atau, ruang putih dilucuti secara ritual dan mudah dibaca:

/s{[exch 32 -1 1{1 index{dup 2 32 string cvrs 0 exch{48 sub add}forall 2 index eq{3 1 roll}{pop}ifelse}forall pop}for pop]}def

Kemudian, jika disimpan bits.psdapat digunakan seperti ini:

gs -q -dBATCH bits.ps -c '[(%stdin)(r)file 1000 string readline pop cvx exec] s =='
825 3944 11746 15342 15752 16375 19944 21826 28436 28943 32425
[16375 15342 32425 11746 19944 28436 28943 3944 15752 825 21826]

Saya pikir ini efektif sama dengan Perl ini (belum ada Perl di sini juga):

sub f{map{$i=$_;grep{$i==(()=(sprintf'%b',$_)=~/1/g)}@_}reverse 1..32}

Meskipun demikian , tidak seperti Postscript, dapat dengan mudah dipasangkan:

sub f{sort{j($b)-j($a)}@_}sub j{$_=sprintf'%b',@_;()=/1/g}
pengguna2846289
sumber
Nota bene! Cinta pertamaku, bahasa favoritku sepanjang masa! Sangat menyenangkan untuk melihat orang percaya lain dalam Bahasa Pemrograman Satu Sejati.
AJMansfield
2

C - 124 111

Diimplementasikan sebagai metode dan menggunakan perpustakaan standar untuk penyortiran. Pointer ke array dan ukuran harus dilewatkan sebagai parameter. Ini hanya akan bekerja pada sistem dengan pointer 32-bit. Pada sistem 64-bit, beberapa karakter harus dihabiskan menentukan definisi pointer.

Lekukan untuk keterbacaan

c(int*a,int*b){
    int d,e,i;
    for(d=e=i=0;i-32;){
        d+=*a>>i&1;e+=*b>>i++&1;
    }
    return d>e?-1:d<e;
}
o(r,s){qsort(r,s,4,c);}

Contoh panggilan:

main() {
    static int a[] ={1, 2, 3, 4, 5, 6, 7, 8, 9};
    o(a, 9);
}
Allbeert
sumber
2

Jawa 8: 144

static void main(String[]a){System.out.print(Stream.of(a).mapToInt(Integer::decode).sorted(Comparable.comparing(Integer::bitCount)).toArray());}

Dalam bentuk yang diperluas:

static void main(String[] args){
    System.out.print(
        Stream.of(args).mapToInt(Integer::decode)
              .sorted(Comparable.comparing(Integer::bitCount))
              .toArray()
        );
}

Seperti yang Anda lihat, ini berfungsi dengan mengonversikan argske a Stream<String>, lalu mengonversikan ke Stream<Integer>dengan dengan Integer::decodereferensi fungsi (lebih pendek dari parseIntatau valueOf), lalu menyortir dengan Integer::bitCount, lalu memasukkannya ke dalam array, dan mencetaknya.

Streaming membuat segalanya lebih mudah.

AJMansfield
sumber