Ordina i numeri in base al conteggio dei binari 1


35

Obbiettivo

Scrivi una funzione o programma ordina un array di numeri interi in ordine decrescente per il numero di 1 presenti nella loro rappresentazione binaria. Non è necessaria alcuna condizione di ordinamento secondaria.

Esempio di elenco ordinato

(utilizzando numeri interi a 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

Ingresso

Un array di numeri interi a 32 bit.

Produzione

Un array con gli stessi numeri interi ordinati come descritto.

punteggio

Questo è il golf del codice per il minor numero di byte da selezionare in una settimana.


2
Non hai menzionato esplicitamente, ma deve essere in ordine decrescente?
Nick T,

3
Hai ragione, mi è mancato. Tutti gli altri sono andati con la discesa, quindi continueremo con quello.
Hand-E-Food,

Penso che il numero finale (21826) sia stato convertito in modo errato. secondo il mio calcolatore di Windows, è 0101 0101 0100 0010, non 0010 1010 1100 0010.
Nzall

Grazie per quelle correzioni. È strano circa 21826 perché ho usato Excel per convertire i numeri in binario. Mi chiedo il resto adesso.
Hand-E-Food,

Soluzione usando le istruzioni assembly e popcount?
eiennohito,

Risposte:


27

J (11)

(\:+/"1@#:)

Questa è una funzione che accetta un elenco:

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

Se vuoi dargli un nome, costa un carattere in più:

     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

Spiegazione:

  • \:: verso il basso ordina
  • +/: somma di
  • "1: ogni riga di
  • #:: rappresentazione binaria

5
@ ak82 è la versione ASCII di APL
John Dvorak,

3
@JanDvorak di sorta; sono state apportate alcune modifiche: jsoftware.com/papers/j4apl.htm (consultare la sezione Lingua).
James Wood,

3
C'è anche quello \:1#.#:che consente di risparmiare qualche byte.
miglia

17

JavaScript, 39

Aggiornamento: ora più corto di 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)

Spiegazione:

q è una funzione ricorsiva. Se x o y sono 0, restituisce x-y(un numero negativo se x è zero o un numero positivo se y è zero). Altrimenti rimuove il bit più basso ( x&x-1) da xey e si ripete.

Versione precedente (42)

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

Questo è davvero intelligente! Sto ancora cercando di pensarci su.
mowwwalker,

Non dovrebbe ~yfunzionare invece di -!y?
Spazzolino da denti

@toothbrush La condizione finale è che x o y siano 0, nel qual caso l'espressione !x|-!ydiventa diversa da zero. ~non si adatta davvero poiché è diverso da zero per molti input (incluso zero)
copia il

Qualcuno può aiutarmi nel caso in cui sia richiesto un ordinamento secondario , per favore?
Manubhargav,

15

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]

2
Semplice. Comprensibile. Corto. Complimenti per questa soluzione.
Pierre Arlaud,


8

Lisp comune, 35

logcountrestituisce il numero di 'on' bit in un numero. Per un elenco l, abbiamo:

(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)

Come funzione autonoma e su cosa baserò il conteggio dei byte:

(lambda(l)(sort l'> :key'logcount))

7

Python 3, 90 77 72 67 caratteri.

La nostra soluzione prende un input dalla riga di comando e stampa il numero in ordine decrescente (67 caratteri) o crescente (66).

Ordine decrescente

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

Grazie a @daniero , per il suggerimento di usare un segno meno nel conteggio di 1 per invertirlo, invece di usare una fetta per invertire l'array alla fine! Ciò ha effettivamente salvato 5 caratteri.

Solo per motivi di pubblicazione, la versione in ordine crescente (che è stata la prima che abbiamo realizzato) avrebbe preso un personaggio in meno.

Ordine crescente :

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

Grazie a @Bakuriu per il suggerimento key = lambda x… . ; D


Quindi 0farà sempre parte del tuo output; Non è corretto
daniero,

Non vedo nulla nella domanda che mi proibisca di inserire un valore.
Jetlef,

Faccio: "Un array con gli stessi numeri interi ordinati come descritto." ;) Inoltre, perché non usare raw_input()e rilasciare alcuni personaggi?
daniero,

1
@daniero ha risolto il problema. Passare a Python 3 (una risposta di Python 2 era già presente, devo essere creativo!) Mi permette di usare input () , salvando due caratteri (due devono essere aggiunti a causa delle parentesi richieste da print () ).
Jetlef,

Puoi lasciar cadere l' []interno sorted. Anche l'output di questo programma è il numero di 1 nei numeri in input ordinati, ma dovresti emettere il numero che hai ricevuto in input, ordinato usando il numero di 1s. Qualcosa del genere: print(sorted(input().split(), key=lambda x:bin(int(x)).count('1')))sarebbe corretto.
Bakuriu,

7

JavaScript [76 byte]

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

dove aè un array di input di numeri.

Test:

[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]

Potresti dire per favore come ..funziona? La mia comprensione è che se x = 5poi eval(x + r)diventa eval(5..toString(2).match(/1/g).length), suppongo, invalido. Grazie.
Gaurang Tandon,

1
@GaurangTandon Non lo è. Come sapete, in JS tutto tranne i letterali è un oggetto. E numeri. Quindi teoricamente (e praticamente) puoi ottenere proprietà o chiamare metodi di qualsiasi non letterale tramite notazione punto, come fai tu 'string'.lengtho [1,2,3].pop(). In caso di numeri puoi fare lo stesso ma tieni presente che dopo un singolo punto il parser cercherà una parte frazionaria del numero aspettandosi un valore float (come in 123.45). Se si utilizza un numero intero si dovrebbe "raccontare" il parser che una parte frazionaria è vuoto, l'impostazione di un punto in più prima di affrontare una proprietà: 123..method().
VisioN,

1
È possibile salvare due byte eliminando gli zeri e trattando il resto come un numero decimale. Sostituisci match(/1/g).lengthcon replace(/0/g,"").
DocMax,

@VisioN Grazie! Ho imparato una cosa nuova.
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]&]&

Uso:

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}


6

k [15 caratteri]

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

Esempio 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

Esempio 2 (tutti i numeri sono 2 ^ n -1)

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

127 63 31 15 7 3

5

Mathematica 39

IntegerDigits[#,2] converte un numero di base 10 in un elenco di 1 e 0.

Tr somma le cifre.

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

Test Case

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

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


Mi sono affezionato a quell'uso (ab?) Di Tr [] nel codice del golf.
Michael Stern,

5

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

Questo non è un programma Java completo, è solo una funzione (un metodo, per essere esatti).

Si presuppone che java.util.Liste java.lang.Long.bitCountsono importati, e ha 60 caratteri:

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

Se non sono consentiti elementi preimportati, eccolo qui con 74 caratteri:

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

Aggiungi altri 7 caratteri se fosse necessario static.

[4 anni dopo] O se preferisci, potrebbe essere un lambda (grazie @KevinCruijssen per il suggerimento), con 48 byte:

a->{a.sort((x,y)->x.bitCount(x)-x.bitCount(y));}

Qualche motivo per cui non puoi farlo Integer.bitCount(x)<Integer.bitCount(y)?-1:1;? Hai bisogno del -1,0,1comportamento?
Giustino,

Inoltre, è possibile sostituire lo <Integer>spazio con?
Giustino,

È inoltre possibile utilizzare Long, che consente di risparmiare un po 'di spazio :)
RobAu

Inoltre a.sort((x,y)->Long.bitCount(x)-Long.bitCount(y));
RobAu,

1
@KevinCruijssen Grazie. Sono così abituato che usare un'istanza variabile per chiamare un metodo statico è una cattiva pratica che ho mai dimenticato che il compilatore lo accetta.
Victor Stafusa,

4

Python 2.x - 65 caratteri (byte)

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

In realtà sono 66 caratteri, 65 se lo rendiamo una funzione (allora hai bisogno di qualcosa per chiamarlo che è lamer da presentare).

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

Demo in 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:]))"

puoi passare sum(int(d)for d in bin(x)[2:])asum(map(int,bin(x)[2:]))
Eliseo il

1
o addirittura:print sorted(input(),key=lambda x:-bin(x).count('1'))
Eliseo,

4

Matlab, 34

Inserisci in 'a'

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

Funziona con numeri non negativi.


4

C - 85 byte (108 106 byte)

Versione portatile su GCC / Clang / ovunque __builtin_popcountsia disponibile (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);}

Versione solo MSVC ultra-condensata, non portatile, a malapena funzionale (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 */

  • La prima riga nuova inclusa nel conteggio byte a causa del #define, le altre non sono necessarie.

  • La funzione da chiamare è s(array, length)conforme alle specifiche.

  • Può hardcodificare la sizeofversione portatile per salvare altri 7 caratteri, come hanno fatto alcune altre risposte C. Non sei sicuro di quale valga la pena di più in termini di rapporto lunghezza-usabilità, decidi tu.


2
sizeof lsalva un byte. Il brutto orribile #define p-__builtin_popcount(può aiutare a salvarne un altro.
ugoren,

@ugoren Grazie per i suggerimenti! Il preprocessore è un tale hack, non avevo idea che una cosa del genere fosse possibile. Purtroppo non funziona su MSVC, ma ogni byte conta!
Thomas,

4

PowerShell v3, 61 58 53

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

ScriptBlock per il Sort-Objectcmdlet restituisce una matrice di 1 per ogni 1 nella rappresentazione binaria del numero. Sort-Objectordina l'elenco in base alla lunghezza dell'array restituito per ciascun numero.

Eseguire:

script.ps1 15342 28943 16375 3944 11746 825 32425 28436 21826 15752 19944

è lavoro. Come funziona? Come la magia "." arriva a "in base alla lunghezza dell'array"?
mazzy,

Il '.' esegue lo scriptblock che lo segue. Il comando sort ordina in base all'output dello scriptblock esterno. Mi rendo conto ora che lo scriptblock interno non è necessario. vedi modifica
Rynant,

$f={è ridondante, while-> for, -band1-> %2, -des-> -de altri trucchi da golf. È chiaro. Puoi spiegare come lavorare $args|sort{@(1,1,...,1)}? È lavoro! In che modo l'ordinamento confronta gli array senza esplicito .Count? dove leggerlo? Grazie!
mazzy

1
@mazzy, hai ragione, ho rimosso i bit ridondanti ora. È l'ordinamento predefinito del cmdlet Sort-Object. Vedi: help Sort-Object -Parameter propertyNon so dove sia definita la proprietà di ordinamento predefinita per i tipi, ma per gli array è Count o Length.
Rynant,

Ottima ipotesi. Ma $args|sort{while($_){if($_-band1){$_};$_=$_-shr1}}-desdà un risultato sbagliato. Pertanto, non lo è Count. È molto interessante. Grazie ancora.
mazzy

3

ECMAScript 6, 61

Presuppone che zsia l'input

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

Dati di test

[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]

Grazie, spazzolino da denti per la soluzione più breve.


1
Ho appena provato la tua soluzione, ma non ha funzionato. Non ordina i numeri.
Spazzolino da denti

@toothbrush woops. Grazie per averlo scoperto, dovrebbe funzionare ora.
Danny,

Ottimo lavoro! Mi piace.
Spazzolino da denti

1
Solo 61 byte: z.sort((a,b)=>{c=d=e=0;while(++c<32)d+=a>>c&1,e+=b>>c&1},e-d)(e grazie per il voto positivo).
Spazzolino da denti

1
La mia soluzione ora ha le stesse dimensioni della tua!
Spazzolino da denti

3

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

-20 grazie all'implementazione di J.Doe -2 in più grazie a Giuseppe

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

Il mio post originale:

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

Provalo online!

Ho provato diversi metodi prima di arrivare a questo risultato.

Metodo Matrix: ho creato una matrice a due colonne, una colonna con il vettore di input, una della somma della rappresentazione binaria, quindi ho ordinato la somma del binario.

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 matrice: realizzato che potrei lanciare la funzione matrice e invece creare un vettore di valori binari, sommarli, ordinarli, quindi utilizzare i valori ordinati per riordinare il vettore di input.

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

Modifiche minori

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

Altre modifiche minori Conversione di tutto in una riga di codice anziché in due separati da un punto e virgola.

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

Metodo somma Invece di aggiungere le colonne con colSumsla matrice binaria creata da sapply, ho aggiunto gli elementi nella colonna prima di sapply"finito".

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

Diminuendo al Rev. Volevo davvero accorciarlo diminuendo, ma R mi scricchiolava se cercavo di accorciare decreasingla orderfunzione, che era necessario per far orderaumentare l'ordine desiderato come impostazione predefinita, quindi mi sono ricordato della revfunzione per invertire un vettore. EUREKA !!! L'ultima modifica nella soluzione finale è stata functionquella pryr::fdi salvare altri 2 byte

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


1
51 byte in miglioramento sull'eccellente golf di @ J.Doe!
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)

Questo è il primo modo in cui ho pensato di risolverlo, ma scommetto che c'è un modo migliore per farlo. Inoltre, se qualcuno conosce un modo per giocare a golf sulle importazioni di Haskell, sarei molto interessato a sentirlo.

Esempio

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

Versione non golfata (con spiegazioni)

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)

sarebbe utile usare la notazione infissa per mod, n`mod`2? Ha la stessa precedenza di moltiplicazione e divisione.
John Dvorak,

Per quanto posso vedere, non sarebbe di grande aiuto per motivi di golf. Perderei due spazi, ma guadagnerei due contraccolpi, giusto?
danmcardle,

import Data.List; import Data.Ord; import Data.Bits; q = sortBy (confrontando popCount) - 80C - o usando il tuo approccio, import DataList; import Data.Ord; b 0 = 0; bn = (mod n 2) + b (div n 2); q = sortBy (confrontando b) - 86C
bazzargh

Ho provato a evitare del tutto le importazioni, la cosa migliore che potevo gestire era 87C giocando a 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.). filtro
bazzargh

2

CoffeeScript (94)

Codice leggibile (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]

Ottimizzato (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

Offuscante (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

Gli operatori ternari sono eccessivamente lunghi (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))

Troppo ancora, ferma il 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)

Finale (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)))

2

Smalltalk (Smalltalk / X), 36 (o forse 24)

input in a; ordina in modo distruttivo in un:

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

versione funzionale: restituisce un nuovo array ordinato:

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

c'è anche una variante più breve (passando il nome o la funzione come argomento) in 24 caratteri. Ma (sospiro) ordinerà per ultimo il più alto. Come ho capito, questo non è stato richiesto, quindi non lo prendo come punteggio di golf:

a sortBySelector:#bitCount

2

PHP 5.4+ 131

Non so nemmeno perché mi preoccupo di PHP, in questo caso:

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

Uso:

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

beh, qualcuno deve preoccuparsi di PHP
Einacio,


2

DFSORT (prodotto di ordinamento IBM Mainframe) 288 (ogni riga di origine ha 72 caratteri, deve avere spazio nella posizione uno)

 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)

Solo per divertimento e niente matematica.

Prende un file (potrebbe essere eseguito da un programma che utilizzava un "array") con gli interi. Prima dell'ordinamento, traduce gli interi in bit (in un campo di 16 caratteri). Quindi cambia gli 0 nei bit in nulla. ORDINA In ordine decrescente sul risultato dei bit modificati. Crea il file ordinato con solo i numeri interi.


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;
  }    
}

4
Dato che si tratta di una competizione di codice golf, dovresti provare ad abbreviare il tuo codice.
Timtech,

2

C #, 88 89

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

Modifica: l'ordine decrescente aggiunge un carattere.


2

Javascript 84

Ispirato da altre risposte javascript, ma senza valutazione e 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));

La domanda è code golf, prova a "golf" il tuo codice: rimuovi gli spazi bianchi non necessari e cerca di rendere il tuo codice il più piccolo possibile. Inoltre, includi un conteggio dei caratteri nella tua risposta.
Programma FOX

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})

2

Postscript, 126

Poiché l'elenco di valori in base al quale ordiniamo è noto in precedenza e molto limitato (32), questa attività può essere facilmente eseguita anche se non è integrato per l'ordinamento, selezionando i valori corrispondenti per 1..32. (È O (32n)? Probabilmente).

La procedura prevede una matrice in pila e restituisce una matrice "ordinata".

/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

Oppure, ritualmente spogliato di spazio bianco e leggibilità:

/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

Quindi, se salvato su di bits.psesso, può essere utilizzato in questo modo:

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]

Penso che sia effettivamente lo stesso di questo Perl (non c'è ancora nessun Perl qui):

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

Anche se che , a differenza di Postscript, può essere facilmente giocato a golf:

sub f{sort{j($b)-j($a)}@_}sub j{$_=sprintf'%b',@_;()=/1/g}

Postscript! Il mio primo amore, la mia lingua preferita di tutti i tempi! È bello vedere un altro credente nell'unico vero linguaggio di programmazione.
AJMansfield,

2

C - 124 111

Implementato come metodo e utilizzando la libreria standard per l'ordinamento. Un puntatore all'array e la dimensione devono essere passati come parametri. Funzionerà solo su sistemi con puntatori a 32 bit. Sui sistemi a 64 bit, alcuni caratteri devono essere spesi specificando le definizioni dei puntatori.

Rientro per leggibilità

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);}

Chiamata di esempio:

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

2

Java 8: 144

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

In forma estesa:

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

Come puoi vedere, funziona convertendo argsin a Stream<String>, quindi convertendolo in a Stream<Integer>con il Integer::decoderiferimento della funzione (più breve di parseInto valueOf), quindi ordinandolo per Integer::bitCount, inserendolo in un array e stampandolo.

I flussi rendono tutto più semplice.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.