Trier les nombres par nombre de 1 binaire

35

Objectif

Ecrivez une fonction ou un programme qui trie un tableau d'entiers dans l'ordre décroissant du nombre de 1 présents dans leur représentation binaire. Aucune condition de tri secondaire n'est nécessaire.

Exemple de liste triée

(en utilisant des entiers 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

Contribution

Un tableau d'entiers 32 bits.

Sortie

Un tableau des mêmes entiers triés comme décrit.

Notation

Il s'agit du code golf pour le plus petit nombre d'octets à sélectionner en une semaine.

Hand-E-Food
la source
2
Vous n'avez pas explicitement mentionné, mais faut-il que ce soit dans un ordre décroissant?
Nick T
3
Vous avez raison, j'ai raté ça. Tous les autres ont opté pour la descente, nous allons donc nous en tenir à cela.
Hand-E-Food le
Je pense que le nombre final (21826) a été mal converti. d'après ma calculatrice Windows, il s'agit de 0101 0101 0100 0010 et non de 0010 1010 1100 0010.
Nzall
Merci pour ces corrections. C'est bizarre avec 21826 parce que j'ai utilisé Excel pour convertir les nombres en binaires. Je m'interroge sur le reste maintenant.
Hand-E-Food le
Solution utilisant les instructions d'assemblage et popcount?
eiennohito

Réponses:

27

J (11)

(\:+/"1@#:)

C'est une fonction qui prend une liste:

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

Si vous voulez lui donner un nom, cela coûte un caractère supplémentaire:

     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

Explication:

  • \:: trier vers le bas
  • +/: somme de
  • "1: chaque rangée de
  • #:: représentation binaire
marinus
la source
5
@ ak82 c'est la version ASCII de APL
John Dvorak le
3
@ JanDvorak en quelque sorte; il y a eu pas mal de changements: jsoftware.com/papers/j4apl.htm (voir la section Langue).
James Wood
3
Il y a aussi \:1#.#:ce qui sauve quelques octets.
miles
17

JavaScript, 39

Mise à jour: maintenant plus court 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)

Explication:

q est une fonction récursive. Si x ou y sont 0, il retourne x-y(un nombre négatif si x est zéro ou un nombre positif si y est zéro). Sinon, il supprime le bit le plus bas ( x&x-1) de x et y et se répète.

Version précédente (42)

x.sort(q=(x,y)=>x^y&&!x-!y+q(x&x-1,y&y-1))
copie
la source
C'est vraiment malin! J'essaie encore de réfléchir à cela.
Mowwwalker
Ne devrait pas ~ytravailler au lieu de -!y?
Brosse à dents
@toothbrush La condition finale est que x ou y valent 0, auquel cas l'expression !x|-!ydevient non nulle. ~ne rentre pas vraiment dans la mesure où il est non nul pour beaucoup d'entrées (y compris zéro)
copie
Quelqu'un peut-il m'aider si un tri secondaire est requis , s'il vous plaît?
Manubhargav
15

Rubis 41

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

Tester:

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
la source
2
Simple. Compréhensible. Court. Bravo pour cette solution.
Pierre Arlaud
8

Python 3 (44):

def f(l):l.sort(lambda n:-bin(n).count('1'))
Mixeur
la source
8

Common Lisp, 35

logcountrenvoie le nombre de bits sur un nombre. Pour une liste l, nous avons:

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

En tant que fonction autonome, et sur quoi je baserai l'octet:

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

Python 3, 90 77 72 67 caractères.

Notre solution prend une entrée de la ligne de commande et imprime le nombre par ordre décroissant (67 caractères) ou croissant (66).

Ordre décroissant

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

Merci à @daniero , pour la suggestion d'utiliser un moins dans le nombre de 1 pour l'inverser, au lieu d'utiliser une tranche pour inverser le tableau à la fin! Cela a effectivement sauvé 5 personnages.

Juste pour le poster, la version à ordre croissant (la première que nous avons créée) prendrait un caractère de moins.

Ordre croissant :

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

Merci à @Bakuriu pour la suggestion clé = lambda x… . ;RÉ

Jetlef
la source
Alors, 0sera toujours une partie de votre sortie alors; Ce n'est pas correct
daniero
Je ne vois rien dans la question qui m'interdit d'insérer une valeur.
Jetlef
Je fais: "Un tableau des mêmes entiers triés comme décrit." ;) Par ailleurs, pourquoi ne pas simplement utiliser raw_input()et supprimer des caractères?
daniero
1
@daniero l'a corrigé. Passer à Python 3 (une réponse Python 2 était déjà présente, faut être créatif!) Me permet d’utiliser input () , en sauvegardant deux caractères (deux doivent être ajoutés à cause des crochets requis par print () ).
Jetlef
Vous pouvez laisser tomber l' []intérieur sorted. Le résultat de ce programme est également le nombre de 1 dans les nombres en entrée triés, mais vous devez indiquer le nombre que vous avez reçu en entrée, trié en fonction du nombre de 1s. Quelque chose comme: print(sorted(input().split(), key=lambda x:bin(int(x)).count('1')))serait correct.
Bakuriu
7

JavaScript [76 octets]

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

aest un tableau d'entrée de nombres.

Tester:

[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]
Vision
la source
Pourriez-vous s'il vous plaît dire comment ça ..marche? Je crois comprendre que si devient x = 5alors ce qui est, je suppose, invalide. Merci. eval(x + r)eval(5..toString(2).match(/1/g).length)
Gaurang Tandon
1
@GaurangTandon Ce n'est pas. Comme vous le savez, dans JS, tout sauf les littéraux est un objet. Et des chiffres. Donc théoriquement (et pratiquement), vous pouvez obtenir des propriétés ou des méthodes d’appel de tous les types non littéraux via la notation par points, comme vous le faites 'string'.lengthou [1,2,3].pop(). En cas de nombre, vous pouvez faire la même chose, mais gardez à l'esprit qu'après un seul point, l'analyseur cherchera une fraction du nombre en attente d'une valeur flottante (comme dans 123.45). Si vous utilisez un nombre entier , vous devez « dire » l'analyseur qu'une partie décimale est vide, la fixation d' un point supplémentaire avant d' aborder une propriété: 123..method().
VisioN
1
Vous pouvez enregistrer deux octets en supprimant les zéros et en traitant le reste comme un nombre décimal. Remplacer match(/1/g).lengthpar replace(/0/g,"").
DocMax
@VisioN Merci! Appris une nouvelle chose.
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]&]&

Usage:

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}

Dr. belisarius
la source
6

k [15 caractères]

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

Exemple 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

Exemple 2 (tous les nombres sont 2 ^ n -1)

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

127 63 31 15 7 3
nyi
la source
5

Mathematica 39

IntegerDigits[#,2] convertit un numéro de base 10 en liste de 1 et de 0.

Tr résume les chiffres.

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

Cas de test

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

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

DavidC
la source
Je me passionne pour cette utilisation (ab?) De Tr [] dans le code de golf.
Michael Stern
5

Java 8 - 87/113 81/111 60/80 60/74/48 caractères

Ce n'est pas un programme Java complet, c'est juste une fonction (une méthode, pour être exact).

Il suppose cela java.util.Listet java.lang.Long.bitCountest importé et comporte 60 caractères:

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

Si aucun élément pré-importé n'est autorisé, le voici avec 74 caractères:

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

Ajoutez plus de 7 caractères si nécessaire static.

[4 ans plus tard] Ou si vous préférez, cela pourrait être un lambda (merci @KevinCruijssen pour la suggestion), avec 48 octets:

a->{a.sort((x,y)->x.bitCount(x)-x.bitCount(y));}
Victor Stafusa
la source
Une raison pour laquelle tu ne peux pas faire Integer.bitCount(x)<Integer.bitCount(y)?-1:1;? Avez-vous besoin du -1,0,1comportement?
Justin
Aussi, est-il possible de remplacer le <Integer>avec de l'espace?
Justin
Vous pouvez aussi utiliser Longpour gagner de la place :)
RobAu
Aussi a.sort((x,y)->Long.bitCount(x)-Long.bitCount(y));
RobAu
1
@ KevinCruijssen Merci. Je suis tellement habitué que l'utilisation d'une instance variable pour appeler une méthode statique est une mauvaise pratique que j'ai jamais oubliée que le compilateur accepte.
Victor Stafusa
4

Python 2.x - 65 caractères (octets)

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

C'est en fait 66 caractères, 65 si nous en faisons une fonction (alors vous avez besoin de quelque chose pour l'appeler qui est plus facile à présenter).

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

Démo dans 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
la source
vous pouvez changer sum(int(d)for d in bin(x)[2:])àsum(map(int,bin(x)[2:]))
Elisha
1
ou même:print sorted(input(),key=lambda x:-bin(x).count('1'))
Elisha, le
4

Matlab, 34 ans

Entrée dans 'a'

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

Fonctionne pour les nombres non négatifs.

fraktal
la source
4

C - 85 octets (108 106 octets)

Version portable sur GCC / Clang / où qu'elle __builtin_popcountsoit disponible (106 octets):

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

Version MSVC uniquement ultra-condensée, non-portable, à peine fonctionnelle (85 octets):

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

  • Première nouvelle ligne incluse dans le nombre d'octets en raison de la #define, les autres ne sont pas nécessaires.

  • La fonction à appeler est s(array, length)conforme aux spécifications.

  • Peut coder sizeofen dur dans la version portable pour enregistrer 7 autres caractères, comme le faisaient quelques autres réponses en C. Vous ne décidez pas lequel vaut le mieux en termes de rapport longueur / convivialité.

Thomas
la source
2
sizeof lenregistre un octet. L'horriblement laid #define p-__builtin_popcount(peut aider à sauver un autre.
Ugoren
@ugoren Merci pour les conseils! Le pré-processeur est un tel bidouillage, je ne savais pas qu'une telle chose était possible. Malheureusement, cela ne fonctionne pas sur MSVC, mais chaque octet compte!
Thomas
4

PowerShell v3, 61 58 53

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

Le ScriptBlock de la Sort-Objectcmdlet renvoie un tableau de 1 pour chaque 1 dans la représentation binaire du nombre. Sort-Objecttrie la liste en fonction de la longueur du tableau retourné pour chaque nombre.

Éxécuter:

script.ps1 15342 28943 16375 3944 11746 825 32425 28436 21826 15752 19944
Rynant
la source
c'est du travail. Comment ça marche? Comment la magie '.' vient à 'basé sur la longueur du tableau'?
mazzy
Le '.' exécute le script qui vient après. La commande de tri effectue un tri en fonction de la sortie du scriptblock externe. Je réalise maintenant que le scriptblock interne n'est pas nécessaire. voir éditer
Rynant
$f={est redondant, while-> for, -band1-> %2, -des-> -det d’autres tours de golf. C'est clair. Pouvez-vous expliquer comment travailler $args|sort{@(1,1,...,1)}? C'est du travail! Comment le type compare les tableaux sans explicite .Count? où lire à ce sujet? Merci!
Mazz
1
@ Mazzy, vous avez raison, j'ai supprimé les bits redondants maintenant. Il s'agit du tri par défaut de la cmdlet Sort-Object. Voir: help Sort-Object -Parameter propertyJe ne sais pas où la propriété de tri par défaut est définie pour les types, mais pour les tableaux, il s'agit du nombre ou de la longueur.
Rynant
Bien deviné. Mais $args|sort{while($_){if($_-band1){$_};$_=$_-shr1}}-desdonne un résultat erroné. Par conséquent, ce n'est pas Count. C'est très intéressant. Merci encore.
Mazz
3

ECMAScript 6, 61

Assume zest l'entrée

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

Données de 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]

Merci, brosse à dents pour la solution plus courte.

Danny
la source
1
Je viens d'essayer votre solution, mais cela n'a pas fonctionné. Cela ne trie pas les chiffres.
Brosse à dents le
@ brosse à dents woops. Merci d'avoir compris, ça devrait marcher maintenant.
Danny
Bon travail! Je l'aime.
Brosse à dents le
1
Seulement 61 octets: z.sort((a,b)=>{c=d=e=0;while(++c<32)d+=a>>c&1,e+=b>>c&1},e-d)(et merci pour le vote positif).
Brosse à dents
1
Ma solution a maintenant la même taille que la vôtre!
Brosse à dents le
3

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

-20 grâce à la mise en œuvre de J.Doe -2 plus grâce à Giuseppe

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

Mon post original:

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

Essayez-le en ligne!

J'ai essayé plusieurs méthodes différentes avant d'arriver à ce résultat.

Méthode matricielle: Création d'une matrice à deux colonnes, une colonne avec le vecteur d'entrée, une de la somme de la représentation binaire, puis j'ai trié sur la somme de binaire.

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-Matrix: Réalisé, je pouvais jeter la fonction de matrice et créer un vecteur de valeurs binaires, les additionner, les ordonner, puis utiliser les valeurs ordonnées pour réorganiser le vecteur d'entrée.

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

Des changements mineurs

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

Autres modifications mineures Conversion de la totalité d'un élément en une ligne de code au lieu de deux séparées par un point-virgule.

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

Méthode Sum Au lieu d'ajouter les colonnes avec colSumsla matrice binaire créée par sapply, j'ai ajouté les éléments de la colonne avant sapply"terminé".

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

Diminution de la valeur de revenant Je voulais vraiment raccourcir décroissant, mais R me reproche si j'essaie de raccourcir decreasingla orderfonction, ce qui était nécessaire pour que l'ordre souhaité orderaugmente par défaut, puis je me souvenais de la revfonction permettant d'inverser un vecteur. EUREKA !!! La dernière modification de la solution finale était functionde pryr::fsauver 2 autres octets

function(x)rev(x[order(sapply(x,function(y)sum(as.double(intToBits(y)))))])
Sumner18
la source
1
53 octets
J.Doe
1
51 octets améliorant l 'excellent golf de @JDoe!
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)

C'est la première façon dont j'ai pensé résoudre ce problème, mais je parie qu'il existe un meilleur moyen de le faire. De plus, si quelqu'un connaissait un moyen de golfer les importations Haskell, je serais très intéressé de l'entendre.

Exemple

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

Version non-golfée (avec explications)

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
la source
serait - il utile d'utiliser la notation infixe pour mod, n`mod`2? Il a la même priorité que la multiplication et la division.
John Dvorak
Cela ne serait pas très utile pour des raisons de golf aussi loin que je peux voir. Je perdrais deux cases, mais deux backticks, non?
danmcardle
import Data.List; import Data.Ord; import Data.Bits; q = sortBy (en comparant popCount) - 80C - ou en utilisant votre approche, importez Data.List; import Data.Ord; b 0 = 0; bn = (mod n 2) + b (div n 2); q = triBy (comparaison b) - 86C
bazzargh
J'ai essayé d'éviter complètement les importations, le mieux que je pouvais gérer était de jouer au 87C en effectuant un tri rapide: 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.). filtre
bazzargh
2

CoffeeScript (94)

Code lisible (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]

Optimisé (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

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

Les opérateurs ternaires sont excessivement longs (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))

Trop long encore, arrêtez de lancer (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)))
Aaron J
la source
2

Smalltalk (Smalltalk / X), 36 (ou peut-être 24)

entrée dans un; trie de manière destructive dans un:

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

version fonctionnelle: renvoie un nouveau tableau trié:

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

il existe même une variante plus courte (en passant le nom ou la fonction en argument) dans 24 caractères. Mais (soupir), cela triera en dernier. Si j'ai bien compris, cela n'a pas été demandé, je ne prends donc pas cela pour un score de golf:

a sortBySelector:#bitCount
blabla999
la source
2

PHP 5.4+ 131

Je ne sais même pas pourquoi je m'embête avec PHP, dans ce cas:

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

Usage:

> 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 décent
la source
Eh
2

Scala, 58

def c(l:List[Int])=l.sortBy(-_.toBinaryString.count(_>48))
Valar Dohaeris
la source
2

DFSORT (produit de tri IBM Mainframe) 288 (chaque ligne source compte 72 caractères et doit comporter un espace en position un)

 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)

Juste pour le plaisir, et pas de mathématiques.

Prend un fichier (peut être exécuté depuis un programme utilisant un "tableau") avec les entiers. Avant le tri, il convertit les nombres entiers en bits (dans un champ de 16 caractères). Puis change les zéro dans les bits à rien. SORT Décroissant sur le résultat des bits modifiés. Crée le fichier trié avec uniquement les entiers.

Bill Woodger
la source
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
la source
4
Puisqu'il s'agit d'une compétition de golf de code, vous devriez essayer de raccourcir votre code.
Timtech
2

C #, 88 89

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

Edit: ordre décroissant ajoute un caractère.

Rik
la source
2

Javascript 84

Inspiré par d'autres réponses javascript, mais sans eval ni 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
la source
La question est le code de golf, essayez de «golfer» votre code: supprimez les espaces inutiles et essayez de rendre votre code aussi petit que possible. En outre, inclure un nombre de caractères dans votre réponse.
ProgramFOX le
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
la source
2

Postscript, 126

Étant donné que la liste des valeurs par lesquelles nous effectuons le tri est connue à l’avance et très limitée (32), cette tâche peut être effectuée facilement, même en l’absence de fonction de tri intégrée, en sélectionnant les valeurs correspondantes pour 1..32. (Est-ce O (32n)? Probablement).

La procédure attend un tableau sur la pile et retourne un tableau 'trié'.

/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, rituellement dépourvu d'espace blanc et de lisibilité:

/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

Ensuite, s’il est sauvegardé, bits.psil peut être utilisé comme ceci:

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]

Je pense que c'est effectivement le même que ce Perl (il n'y a pas encore de Perl ici aussi):

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

Bien que cela , contrairement à Postscript, puisse être facilement joué au golf:

sub f{sort{j($b)-j($a)}@_}sub j{$_=sprintf'%b',@_;()=/1/g}
utilisateur2846289
la source
Postscript! Mon premier amour, ma langue préférée de tous les temps! Il est agréable de voir un autre croyant dans le langage de programmation One True.
AJMansfield
2

C - 124 111

Implémenté en tant que méthode et en utilisant la bibliothèque standard pour le tri. Un pointeur sur le tableau et la taille doivent être passés en tant que paramètres. Cela ne fonctionnera que sur des systèmes avec des pointeurs 32 bits. Sur les systèmes 64 bits, certains caractères doivent être utilisés pour spécifier les définitions de pointeur.

Indentation pour la lisibilité

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

Exemple d'appel:

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

Java 8: 144

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

Sous forme développée:

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

Comme vous pouvez le constater, cela fonctionne en convertissant le argsen a Stream<String>, puis en un Stream<Integer>avec la Integer::decoderéférence de fonction (plus court que parseIntou valueOf), puis en triant Integer::bitCount, en le plaçant dans un tableau et en l'imprimant.

Les flux rendent tout plus facile.

AJMansfield
la source