Classificar números pela contagem de 1 binários


35

Objetivo

Escreva uma função ou programa que classifique uma matriz de números inteiros em ordem decrescente pelo número de 1's presentes em sua representação binária. Nenhuma condição de classificação secundária é necessária.

Exemplo de lista classificada

(usando números inteiros 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

Uma matriz de números inteiros de 32 bits.

Saída

Uma matriz dos mesmos números inteiros classificados como descrito.

Pontuação

Esse é o código golf para o menor número de bytes a ser selecionado em uma semana.


2
Você não mencionou explicitamente, mas precisa estar em ordem decrescente?
Nick T

3
Você está certo, eu senti falta disso. Todo mundo já desceu, então vamos continuar com isso.
Hand-E-Food,

Eu acho que o número final (21826) foi convertido errado. de acordo com a minha calculadora do Windows, é 0101 0101 0100 0010, e não 0010 1010 1100 0010.
Nzall

Obrigado por essas correções. Isso é estranho no 21826 porque usei o Excel para converter os números em binários. Eu me pergunto sobre o resto agora.
Mão-E-Comida

Solução usando instruções de montagem e contagem pop-up?
21714 Eiennohito

Respostas:


27

J (11)

(\:+/"1@#:)

Esta é uma função que leva uma lista:

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

Se você quiser dar um nome, custa um caractere extra:

     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

Explicação:

  • \:: classificar para baixo em
  • +/: soma de
  • "1: cada linha de
  • #:: representação binária

5
@ ak82 é a versão ASCII da APL
John Dvorak

3
@JanDvorak das sortes; houve algumas mudanças: jsoftware.com/papers/j4apl.htm (consulte a seção Idioma).
James Wood

3
Há também o \:1#.#:que salva alguns bytes.
milhas

17

JavaScript, 39

Atualização: Agora menor que o 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)

Explicação:

q é uma função recursiva. Se x ou y forem 0, ele retornará x-y(um número negativo se x for zero ou um número positivo se y for zero). Caso contrário, ele remove o bit mais baixo ( x&x-1) de x e ye repete.

Versão anterior (42)

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

Isso é realmente inteligente! Eu ainda estou tentando entender isso.
mowwwalker

Não deveria ~yfuncionar em vez de -!y?
Escova de dentes

@toothbrush A condição final é que x ou y são 0; nesse caso, a expressão !x|-!yse torna diferente de zero. ~realmente não se encaixa, pois é diferente de zero para muitas entradas (incluindo zero)
copie

Alguém pode me ajudar no caso de uma classificação secundária ser necessária , por favor?
Manubhargav

15

Ruby 41

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

Teste:

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
Simples. Compreensível. Baixo. Parabéns por esta solução.
Pierre Arlaud


8

Lisp comum, 35

logcountretorna o número de 'on' bits em um número. Para uma lista l, temos:

(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 uma função autônoma, e no que basearemos a contagem de bytes:

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

7

Python 3, 90 77 72 67 caracteres.

Nossa solução obtém uma entrada da linha de comando e imprime o número em ordem decrescente (67 caracteres) ou crescente (66).

Ordem decrescente

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

Obrigado a @daniero , pela sugestão de usar um sinal de menos na contagem de 1 para reverter isso, em vez de usar uma fatia para reverter a matriz no final! Isso efetivamente salvou 5 caracteres.

Apenas para publicá-lo, a versão da ordem crescente (que foi a primeira que fizemos) levaria um caractere a menos.

Ordem crescente :

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

Obrigado a @Bakuriu pela sugestão = lambda x… . ; D


Então 0sempre fará parte da sua saída; Isso não está correto.
Daniero

Não vejo nada na pergunta que me proíba de inserir um valor.
Jetlef

Eu faço: "Uma matriz dos mesmos números inteiros classificados como descrito." ;) Além disso, por que não usar raw_input()e soltar alguns caracteres?
Daniero

11
@daniero corrigiu. Mudar para o Python 3 (uma resposta do Python 2 já estava presente, precisa ser criativo!) Me permite usar input () , salvando dois caracteres (dois devem ser adicionados por causa dos colchetes exigidos pelo print () ).
Jetlef 19/02

Você pode largar o []interior sorted. Além disso, a saída deste programa é o número de 1s nos números da entrada classificados, mas você deve exibir o número recebido na entrada, classificado usando o número de 1s. Algo como: print(sorted(input().split(), key=lambda x:bin(int(x)).count('1')))estaria correto.
Bakuriu

7

JavaScript [76 bytes]

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

onde aé uma matriz de entrada de números.

Teste:

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

Poderia dizer como ..funciona? Meu entendimento é que, se x = 5então se eval(x + r)torna o eval(5..toString(2).match(/1/g).length)que, suponho, é inválido. Obrigado.
Gaurang Tandon

11
@GaurangTandon Não é. Como você sabe, em JS, tudo, exceto literais, é um objeto. E números. Então, teoricamente (e praticamente), você pode obter propriedades ou chamar métodos de qualquer não literal por meio de notação de ponto, como você 'string'.lengthou [1,2,3].pop(). No caso de números, você pode fazer o mesmo, mas lembre-se de que, após um único ponto, o analisador procurará uma parte fracionária do número que espera um valor flutuante (como em 123.45). Se você usar um inteiro você deve "dizer" o analisador de que uma parte fracionária é vazio, definindo um ponto extra antes de abordar uma propriedade: 123..method().
VisioN

11
Você pode salvar dois bytes removendo os zeros e tratando o restante como um número decimal. Substitua match(/1/g).lengthpor replace(/0/g,"").
DocMax 19/02

@VisioN Thanks! Aprendeu uma coisa nova.
Gaurang Tandon

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

Exemplo 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

Exemplo 2 (todos os números são 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 um número base 10 na lista de 1 e 0.

Tr soma os dígitos.

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

Caso de teste

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

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


Eu me apaixonei por esse (ab?) Uso de Tr [] no código de golfe.
Michael Stern

5

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

Este não é um programa java completo, é apenas uma função (um método, para ser exato).

Ele assume que java.util.Liste java.lang.Long.bitCounté importado e tem 60 caracteres:

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

Se nenhum material pré-importado for permitido, aqui está com 74 caracteres:

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

Adicione mais 7 caracteres, se for necessário static.

[4 anos depois] Ou, se preferir, pode ser um lambda (obrigado @KevinCruijssen pela sugestão), com 48 bytes:

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

Alguma razão pela qual você não pode fazer Integer.bitCount(x)<Integer.bitCount(y)?-1:1;? Você precisa do -1,0,1comportamento?
Justin

Além disso, é possível substituir o <Integer>espaço com?
23714 Justin

Você também pode usar Long, que poupar espaço :)
Robau

Também a.sort((x,y)->Long.bitCount(x)-Long.bitCount(y));
RobAu

11
@KevinCruijssen Thanks. Estou tão acostumado que usar uma instância variável para chamar um método estático é uma prática ruim que já esqueci que o compilador aceita isso.
Victor Stafusa

4

Python 2.x - 65 caracteres (bytes)

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

Na verdade, são 66 caracteres, 65 se fizermos isso uma função (então você precisa de algo para chamá-lo, que é lamer para apresentar).

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

Demonstração no 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:]))"

você pode mudar sum(int(d)for d in bin(x)[2:])parasum(map(int,bin(x)[2:]))
Eliseu

11
ou até mesmo:print sorted(input(),key=lambda x:-bin(x).count('1'))
Eliseu

4

Matlab, 34

Entrada em 'a'

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

Funciona para números não negativos.


4

C - 85 bytes (108 106 bytes)

Versão portátil no GCC / Clang / onde quer que __builtin_popcountesteja disponível (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);}

Versão ultracondensada, não portátil, apenas funcional para 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 */

  • A primeira nova linha incluída na contagem de bytes, por causa do #define, os outros não são necessários.

  • A função a ser chamada está de s(array, length)acordo com as especificações.

  • É possível codificar sizeofna versão portátil para salvar outros 7 caracteres, como algumas outras respostas em C fizeram. Não tenho certeza de qual deles vale mais em termos de relação comprimento / usabilidade, você decide.


2
sizeof lsalva um byte. O horrivelmente feio #define p-__builtin_popcount(pode ajudar a salvar outro.
ugoren

@ugoren Obrigado pelas dicas! O pré-processador é um hack, eu não fazia ideia de que isso era possível. Infelizmente, ele não funciona no MSVC, mas cada byte conta!
Thomas

4

PowerShell v3, 61 58 53

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

O ScriptBlock do Sort-Objectcmdlet retorna uma matriz de 1 para cada 1 na representação binária do número. Sort-Objectclassifica a lista com base no comprimento da matriz retornada para cada número.

Executar:

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

isso funciona. Como isso funciona? Como a mágica '.' trata de 'com base no comprimento da matriz'?
Mazzy

O '.' executa o scriptblock que vem depois dele. O comando sort classifica com base na saída do scriptblock externo. Percebo agora que o scriptblock interno não é necessário. ver edição
Rynant 2/11

$f={é redundante, while-> for, -band1-> %2, -des-> -de outros truques de golfe. Está claro. Você pode explicar como trabalhar $args|sort{@(1,1,...,1)}? Isso funciona! Como a classificação compara matrizes sem explícito .Count? onde ler sobre isso? Obrigado!
Mazzy

11
@mazzy, você está certo, eu removi os bits redundantes agora. É a classificação padrão do cmdlet Sort-Object. Consulte: help Sort-Object -Parameter propertyNão sei onde a propriedade de classificação padrão para tipos está definida, mas para matrizes é Contagem ou Comprimento.
Rynant 2/11

Bom palpite. Mas $args|sort{while($_){if($_-band1){$_};$_=$_-shr1}}-desdá um resultado errado. Portanto, não é Count. É muito interessante. Obrigado novamente.
Mazzy

3

ECMAScript 6, 61

Assume que zé a entrada

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

Dados de teste

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

Obrigado, escova de dentes para a solução mais curta.


11
Acabei de experimentar sua solução, mas não funcionou. Não classifica os números.
Escova de dentes

@toothbrush woops. Obrigado por capturar isso, deve funcionar agora.
Danny

Ótimo trabalho! Eu gosto disso.
Escova de dentes

11
Apenas 61 bytes: z.sort((a,b)=>{c=d=e=0;while(++c<32)d+=a>>c&1,e+=b>>c&1},e-d)(e obrigado pelo voto positivo).
Escova de dentes

11
Minha solução agora é do mesmo tamanho que a sua!
Escova de dentes

3

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

-20 graças à implementação de J.Doe -2 mais graças a Giuseppe

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

Minha postagem original:

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

Experimente online!

Eu tentei vários métodos diferentes antes de chegar a esse resultado.

Método da matriz: Criou uma matriz de duas colunas, uma coluna com o vetor de entrada, uma da soma da representação binária e, em seguida, classifiquei a soma do binário.

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

Não matriz: percebi que eu poderia jogar fora a função da matriz e criar um vetor de valores binários, somar, ordená-los e depois usar os valores ordenados para reordenar o vetor de entrada.

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

Pequenas alterações

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

Mais pequenas alterações Convertendo tudo para uma linha de código em vez de duas separadas por ponto e vírgula.

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

Método Sum Em vez de adicionar as colunas com colSumsa matriz binária criada por sapply, adicionei os elementos na coluna antes de sapply"terminar".

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

Diminuindo para Rev Eu realmente queria diminuir a diminuição, mas R grita comigo se eu tentar diminuir decreasinga orderfunção, necessária para obter a ordem desejada como orderpadrão para aumentar, então lembrei da revfunção de reverter um vetor. EUREKA !!! A última mudança na solução final foi functionpara pryr::fsalvar mais 2 bytes

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


11
51 bytes melhorando o excelente golfe do @ 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 é a primeira maneira que pensei em resolver isso, mas aposto que há uma maneira melhor de fazer isso. Além disso, se alguém souber uma maneira de jogar golfe nas importações de Haskell, eu ficaria muito interessado em ouvi-la.

Exemplo

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

Versão não destruída (com explicações)

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)

seria útil usar a notação infix para mod, n`mod`2? Tem a mesma precedência que multiplicação e divisão.
John Dvorak

Isso não seria muito útil por razões de golfe, tanto quanto eu posso ver. Eu perderia dois espaços, mas ganharia dois backticks, certo?
Danmcardle

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

Eu tentei evitar importações totalmente, o melhor que consegui gerenciar foi 87C jogando golfe de forma rápida: b 0 = 0; bn = mod n 2 + b (div n 2); q [] = []; q (a: c) = f ( (b>). b) c ++ a: f ((ba <=). b) c; f = (q.). filter
bazzargh

2

CoffeeScript (94)

Código legível (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]

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

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

Os operadores ternários são excessivamente longos (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))

Ainda por muito tempo, pare de transmitir (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 (ou talvez 24)

entrada em a; classifica destrutivamente um:

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

versão funcional: retorna uma nova matriz classificada:

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

existe ainda uma variante mais curta (passando o nome ou a função como argumento) em 24 caracteres. Mas (suspiro) ele será o mais alto por último. Pelo que entendi, isso não foi solicitado, por isso não considero isso como pontuação de golfe:

a sortBySelector:#bitCount

2

PHP 5.4+ 131

Eu nem sei por que me preocupo com PHP, neste 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
)

bem, alguém tem que se preocupar com PHP
Einacio


2

DFSORT (produto de classificação IBM Mainframe) 288 (cada linha de origem possui 72 caracteres, deve ter espaço na posição um)

 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)

Apenas por diversão e sem matemática.

Pega um arquivo (pode ser executado a partir de um programa que usou uma "matriz") com os números inteiros. Antes da classificação, ele converte os números inteiros em bits (em um campo de 16 caracteres). Em seguida, altera os 0s nos bits para nada. ORDENAR Descendente do resultado dos bits alterados. Cria o arquivo classificado apenas com os números inteiros.


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
Como esta é uma competição de código de golfe, você deve tentar encurtar seu código.
Timtech 19/02/14

2

C #, 88 89

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

Editar: ordem decrescente adiciona um caractere.


2

Javascript 84

Inspirado por outras respostas javascript, mas sem eval 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));

A questão é o código golf, por favor, tente 'golf' o seu código: remova o espaço em branco desnecessário e tente torná-lo o menor possível. Além disso, inclua uma contagem de caracteres em sua resposta.
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

Postscript, 126

Como a lista de valores pelos quais classificamos é conhecida de antemão e é muito limitada (32), essa tarefa pode ser realizada facilmente, mesmo que não haja uma classificação interna, escolhendo valores correspondentes para 1 .. 32. (É O (32n)? Provavelmente).

O procedimento espera a matriz na pilha e retorna a matriz 'classificada'.

/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

Ou, ritualmente sem espaço em branco e legibilidade:

/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

Então, se salvo em bits.ps nele, pode ser usado assim:

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]

Eu acho que efetivamente é o mesmo que este Perl (ainda não há Perl aqui também):

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

Embora isso , ao contrário do Postscript, possa ser facilmente jogado:

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

Postscript! Meu primeiro amor, minha língua favorita de todos os tempos! É bom ver outro crente na One True Programming Language.
AJMansfield

2

C - 124 111

Implementado como um método e usando a biblioteca padrão para a classificação. Um ponteiro para a matriz e o tamanho devem ser passados ​​como parâmetros. Isso funcionará apenas em sistemas com ponteiros de 32 bits. Em sistemas de 64 bits, alguns caracteres precisam ser gastos especificando definições de ponteiro.

Recuo para facilitar a leitura

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

Exemplo de chamada:

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

Em forma expandida:

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

Como você pode ver, isso funciona convertendo argspara para Stream<String>e depois para Stream<Integer>com a Integer::decodereferência de função (menor queparseInt ou valueOf) e, em seguida, classificando porInteger::bitCount , colocando-o em uma matriz e imprimindo-o.

Os fluxos tornam tudo mais fácil.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.