Ordenar números por recuento de 1 binario


35

Gol

Escriba una función o programa, ordene una matriz de enteros en orden descendente por el número de 1 presente en su representación binaria. No es necesaria una condición de clasificación secundaria.

Ejemplo de lista ordenada

(usando enteros de 16 bits)

  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

Entrada

Una matriz de enteros de 32 bits.

Salida

Una matriz de los mismos enteros ordenados como se describe.

Tanteo

Este es el código de golf para el menor número de bytes que se seleccionará en una semana.


2
No mencionaste explícitamente, pero ¿tiene que estar en orden descendente?
Nick T

3
Tienes razón, me perdí eso. Todos los demás han ido descendiendo, así que nos quedaremos con eso.
Hand-E-Food

Creo que el número final (21826) se ha convertido incorrectamente. según mi calculadora de Windows, es 0101 0101 0100 0010, no 0010 1010 1100 0010.
Nzall

Gracias por esas correcciones. Eso es extraño sobre 21826 porque usé Excel para convertir los números a binario. Me pregunto sobre el resto ahora.
Hand-E-Food

¿Solución usando instrucciones de ensamblaje y popcount?
eiennohito

Respuestas:


27

J (11)

(\:+/"1@#:)

Esta es una función que toma una lista:

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

Si quieres darle un nombre, cuesta un personaje adicional:

     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

Explicación:

  • \:: ordenar hacia abajo
  • +/: la suma de
  • "1: cada fila de
  • #:: representación binaria

55
@ ak82 es la versión ASCII de APL
John Dvorak

3
@ JanDvorak de algún tipo; ha habido bastantes cambios: jsoftware.com/papers/j4apl.htm (consulte la sección Idioma).
James Wood

3
También hay \:1#.#:que ahorra unos pocos bytes.
millas

17

JavaScript, 39

Actualización: ahora más corto que 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)

Explicación:

q es una función recursiva. Si x o y son 0, devuelve x-y(un número negativo si x es cero o un número positivo si y es cero). De lo contrario, elimina el bit más bajo ( x&x-1) de x e y y se repite.

Versión anterior (42)

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

¡Esto es realmente inteligente! Todavía estoy tratando de entenderlo.
mowwwalker

¿No debería ~yfuncionar en lugar de -!y?
Cepillo de dientes

@toothbrush La condición final es que x o y son 0, en cuyo caso la expresión se !x|-!yvuelve distinta de cero. ~realmente no encaja ya que no es cero para muchas entradas (incluido cero)
copie

¿Alguien puede ayudarme en caso de que se requiera una clasificación secundaria , por favor?
Manubhargav

15

Rubí 41

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

Prueba:

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
Simple. Comprensible. Corto. Felicitaciones por esta solución.
Pierre Arlaud


8

Lisp común, 35

logcountdevuelve el número de bits 'en' en un número. Para una lista l, tenemos:

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

Como una función independiente, y en lo que basaré la cuenta de bytes:

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

7

Python 3, 90 77 72 67 caracteres.

Nuestra solución toma una entrada de la línea de comando e imprime el número en orden descendente (67 caracteres) o ascendente (66).

Orden descendiente

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

Gracias a @daniero , por la sugerencia de usar un menos en el recuento de 1 para revertirlo, en lugar de usar un corte para revertir la matriz al final. Esto efectivamente ahorró 5 caracteres.

Solo por el hecho de publicarlo, la versión de orden ascendente (que fue la primera que hicimos) tomaría un personaje menos.

Orden ascendente :

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

Gracias a @Bakuriu por la clave = lambda x ... sugerencia. ;RE


Entonces 0siempre será una parte de su producción; Eso no es correcto
daniero

No veo nada en la pregunta que me prohíba insertar un valor.
Jetlef

Lo hago: "Una matriz de los mismos enteros ordenados como se describe". ;) Además, ¿por qué no usar raw_input()y soltar algunos caracteres?
daniero

1
@daniero lo arregló. Cambiar a Python 3 (ya estaba presente una respuesta de Python 2, ¡tengo que ser creativo!) Me permite usar input () , guardando dos caracteres (se deben agregar dos debido a los corchetes requeridos por print () ).
Jetlef

Puedes dejar caer el []interior sorted. Además, la salida de este programa es el número de 1s en los números de entrada ordenados, pero debe generar el número que recibió en la entrada, ordenados usando el número de 1s. Algo así como: print(sorted(input().split(), key=lambda x:bin(int(x)).count('1')))sería correcto.
Bakuriu

7

JavaScript [76 bytes]

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

donde aes una matriz de entrada de números.

Prueba:

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

¿Podrías decir cómo ..funciona? Tengo entendido que si x = 5luego se eval(x + r)convierte en lo eval(5..toString(2).match(/1/g).length)que, supongo, no es válido. Gracias.
Gaurang Tandon

1
@GaurangTandon No lo es. Como sabes, en JS todo, excepto los literales, es un objeto. Y números. Entonces, teóricamente (y prácticamente) puede obtener propiedades o métodos de llamada de cualquier no literal a través de la notación de puntos, como lo hace 'string'.lengtho [1,2,3].pop(). En el caso de los números, puede hacer lo mismo, pero debe tener en cuenta que después de un solo punto, el analizador buscará una parte fraccionaria del número que espera un valor flotante (como en 123.45). Si utiliza un número entero que debe "decir" al analizador que una parte fraccionaria está vacía, el establecimiento de un punto extra antes de abordar una propiedad: 123..method().
VisioN

1
Puede guardar dos bytes quitando los ceros y tratando el resto como un número decimal. Reemplazar match(/1/g).lengthcon replace(/0/g,"").
DocMax

@VisioN ¡Gracias! Aprendí algo nuevo.
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 caracteres]

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

Ejemplo 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

Ejemplo 2 (todos los números son 2 ^ n -1)

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

127 63 31 15 7 3

5

Mathematica 39

IntegerDigits[#,2] convierte un número base 10 en una lista de 1 y 0.

Tr suma los dígitos.

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

Caso de prueba

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

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


Me he aficionado al uso (ab?) De Tr [] en el código de golf.
Michael Stern

5

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

Este no es un programa completo de Java, es solo una función (un método, para ser exactos).

Asume eso java.util.Listy java.lang.Long.bitCountse importan, y tiene 60 caracteres:

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

Si no se permiten elementos preimportados, aquí tiene 74 caracteres:

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

Agregue más 7 caracteres si fuera necesario static.

[4 años después] O si lo prefiere, podría ser un lambda (gracias @KevinCruijssen por la sugerencia), con 48 bytes:

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

¿Alguna razón por la que no puedes hacer Integer.bitCount(x)<Integer.bitCount(y)?-1:1;? ¿Necesitas el -1,0,1comportamiento?
Justin

Además, ¿es posible reemplazar el <Integer>espacio?
Justin

También puede usar Long, que ahorra algo de espacio :)
RobAu

También a.sort((x,y)->Long.bitCount(x)-Long.bitCount(y));
RobAu

1
@KevinCruijssen Gracias. Estoy tan acostumbrado que usar una instancia variable para llamar a un método estático es una mala práctica que alguna vez olvidé que el compilador lo acepta.
Victor Stafusa

4

Python 2.x - 65 caracteres (bytes)

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

En realidad, son 66 caracteres, 65 si lo hacemos una función (entonces necesita algo para llamarlo que es más difícil de presentar).

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

Demostración en 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:]))"

puedes cambiar sum(int(d)for d in bin(x)[2:])asum(map(int,bin(x)[2:]))
Elisha

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

4

Matlab, 34

Entrada en 'a'

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

Funciona para números no negativos.


4

C - 85 bytes (108 106 bytes)

Versión portátil en GCC / Clang / donde __builtin_popcountesté disponible (106 bytes):

#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ón ultra condensada, no portátil, apenas funcional MSVC (85 bytes):

#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 */

  • Primera línea nueva incluida en el recuento de bytes debido a que #define, los otros no son necesarios.

  • La función para llamar está de s(array, length)acuerdo con las especificaciones.

  • Puede codificar sizeofen la versión portátil para guardar otros 7 caracteres, como hicieron algunas otras respuestas de C. No estoy seguro de cuál vale más en términos de relación longitud-usabilidad, usted decide.


2
sizeof lGuarda un byte. Lo horriblemente feo #define p-__builtin_popcount(puede ayudar a salvar a otro.
ugoren

@ugoren Gracias por los consejos! El preprocesador es un truco, no tenía idea de que tal cosa fuera posible. Lamentablemente, no funciona en MSVC, ¡pero cada byte cuenta!
Thomas

4

PowerShell v3, 61 58 53

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

El ScriptBlock para el Sort-Objectcmdlet devuelve una matriz de 1 para cada 1 en la representación binaria del número. Sort-Objectordena la lista en función de la longitud de la matriz devuelta para cada número.

Ejecutar:

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

es trabajo. ¿Como funciona? Cómo la magia '. viene a 'basado en la longitud de la matriz'?
mazzy

Los '.' ejecuta el bloque de script que viene después. El comando de clasificación se basa en la salida del bloque de script externo. Ahora me doy cuenta de que el bloque de script interno no es necesario. ver edición
Rynant

$f={es redundante, while-> for, -band1-> %2, -des-> -dy otros trucos de golf. Está vacío. ¿Puedes explicar cómo trabajar $args|sort{@(1,1,...,1)}? ¡Es trabajo! ¿Cómo se compara el ordenamiento de matrices sin explícito .Count? ¿Dónde leer al respecto? ¡Gracias!
mazzy

1
@mazzy, tienes razón, eliminé los bits redundantes ahora. Es la ordenación predeterminada del cmdlet Sort-Object. Consulte: help Sort-Object -Parameter propertyNo sé dónde se define la propiedad de clasificación predeterminada para los tipos, pero para las matrices es Count o Length.
Rynant

Buena suposición. Pero $args|sort{while($_){if($_-band1){$_};$_=$_-shr1}}-desda un resultado incorrecto. Por lo tanto, no lo es Count. Es muy interesante. Gracias de nuevo.
mazzy

3

ECMAScript 6, 61

Asume zes la entrada

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

Datos de prueba

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

Gracias, cepillo de dientes para la solución más corta.


1
Acabo de probar su solución, pero no funcionó. No ordena los números.
Cepillo de dientes

@ Bluetoothbrush woops. Gracias por atrapar eso, debería funcionar ahora.
Danny

¡Buen trabajo! Me gusta.
Cepillo de dientes

1
Solo 61 bytes: z.sort((a,b)=>{c=d=e=0;while(++c<32)d+=a>>c&1,e+=b>>c&1},e-d)(y gracias por el voto positivo).
Cepillo de dientes

1
¡Mi solución ahora es del mismo tamaño que la tuya!
Cepillo de dientes

3

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

-20 gracias a la implementación de J.Doe -2 más gracias a Giuseppe

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

Mi post original:

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

Pruébalo en línea!

Probé varios métodos diferentes antes de llegar a este resultado.

Método de matriz: Creé una matriz de dos columnas, una columna con el vector de entrada, una de la suma de la representación binaria, luego ordené la suma de 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),]}

No matricial: me di cuenta de que podía descartar la función matricial y en su lugar crear un vector de valores binarios, sumarlos, ordenarlos y luego usar los valores ordenados para reordenar el vector de entrada.

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

Cambios menores

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

Más cambios menores Convertir todo en una línea de código en lugar de dos separadas por un punto y coma.

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

Método de suma En lugar de agregar las columnas con colSumsla matriz binaria creada por sapply, agregué los elementos en la columna antes de sapply"terminar".

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

Disminuir a Rev Realmente quería acortar la disminución, pero R me grita si trato de acortar decreasingla orderfunción, que era necesaria para obtener el orden deseado como ordervalores predeterminados para aumentar, luego recordé la revfunción de invertir un vector. EUREKA !!! El último cambio en la solución final fue functiona pryr::fsalvar más de 2 bytes

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


1
¡51 bytes mejorando en el excelente golf de @ 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)

Esta es la primera forma en que pensé en resolver esto, pero apuesto a que hay una mejor manera de hacerlo. Además, si alguien conoce una forma de jugar al golf con las importaciones de Haskell, me interesaría mucho escucharla.

Ejemplo

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

Versión sin golf (con explicaciones)

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)

sería útil usar la notación infija a mod, n`mod`2? Tiene la misma precedencia que la multiplicación y la división.
John Dvorak

Por lo que puedo ver, eso no sería demasiado útil por razones de golf. Perdería dos espacios, pero ganaría dos backticks, ¿verdad?
danmcardle

import Data.List; import Data.Ord; import Data.Bits; q = sortBy (comparando popCount) - 80C - o usando su enfoque, importe Data.List; import Data.Ord; b 0 = 0; bn = (mod n 2) + b (div n 2); q = sortBy (comparando b) - 86C
bazzargh

Traté de evitar las importaciones por completo, lo mejor que pude manejar fue 87C jugando 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)

Código legible (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]

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

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

Los operadores ternarios son excesivamente largos (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))

Demasiado tiempo aún, deja de lanzar (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)))

2

Smalltalk (Smalltalk / X), 36 (o tal vez 24)

entrada en a; clasifica destructivamente en un:

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

versión funcional: devuelve una nueva matriz ordenada:

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

Incluso hay una variante más corta (pasando el nombre o la función como argumento) en 24 caracteres. Pero (suspiro) se ordenará más alto al final. Como entendí, esto no fue solicitado, así que no lo tomo como puntaje de golf:

a sortBySelector:#bitCount

2

PHP 5.4+ 131

Ni siquiera sé por qué me molesto con PHP, en este 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
)

bueno, alguien tiene que molestarse con PHP
Einacio


2

DFSORT (producto de clasificación de mainframe de IBM) 288 (cada línea de origen tiene 72 caracteres, debe tener espacio en la posición 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 por diversión y sin matemáticas.

Toma un archivo (podría ejecutarse desde un programa que utilizó una "matriz") con los enteros. Antes de ordenar, traduce los enteros a bits (en un campo de 16 caracteres). Luego cambia los ceros en los bits a nada. ORDENAR Desciende según el resultado de los bits modificados. Crea el archivo ordenado solo con los enteros.


2

do

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

44
Como se trata de una competencia de código de golf, debe intentar acortar su código.
Timtech

2

C #, 88 89

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

Editar: el orden descendente agrega un carácter.


2

Javascript 84

Inspirado en otras respuestas de JavaScript, pero sin eval y 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 pregunta es el código golf, por favor intente "golf" su código: elimine espacios en blanco innecesarios e intente hacer su código lo más pequeño posible. Además, incluya un recuento de caracteres en su respuesta.
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})

2

Postdata, 126

Debido a que la lista de valores por la que clasificamos se conoce de antemano y es muy limitada (32), esta tarea se puede hacer fácilmente incluso si no hay una función incorporada para ordenar, eligiendo valores coincidentes para 1..32. (¿Es O (32n)? Probablemente).

El procedimiento espera una matriz en la pila y devuelve una matriz 'ordenada'.

/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

O, despojado ritualmente de espacios en blanco y legibilidad:

/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

Luego, si se guarda en bits.psél, puede usarse así:

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]

Creo que efectivamente es lo mismo que este Perl (todavía no hay Perl aquí también):

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

Aunque eso , a diferencia de PostScript, se puede jugar fácilmente:

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

¡Posdata! ¡Mi primer amor, mi idioma favorito de todos los tiempos! Es agradable ver a otro creyente en el Lenguaje de Programación Verdadero.
AJMansfield

2

C - 124 111

Implementado como método y utilizando la biblioteca estándar para la clasificación. Un puntero a la matriz y el tamaño deben pasarse como parámetros. Esto solo funcionará en sistemas con punteros de 32 bits. En los sistemas de 64 bits, algunos caracteres deben gastarse especificando definiciones de puntero.

Sangría para legibilidad

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

Llamada de muestra:

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

En forma expandida:

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

Como puede ver, esto funciona convirtiendo argsa a Stream<String>, luego convirtiendo a a Stream<Integer>con la Integer::decodereferencia de función (más corta que parseInto valueOf), y luego ordenando porInteger::bitCount , luego colocándolo en una matriz e imprimiéndolo.

Las transmisiones hacen que todo sea más fácil.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.