Сортировать числа по двоичному 1


35

Цель

Напишите функцию или программу, отсортирующую массив целых чисел в порядке убывания по количеству единиц, присутствующих в их двоичном представлении. Никаких дополнительных условий сортировки не требуется.

Пример отсортированного списка

(используя 16-битные целые числа)

  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

вход

Массив 32-битных целых чисел.

Выход

Массив из тех же целых чисел отсортирован, как описано.

счет

Это код гольфа для наименьшего количества байтов, которые будут выбраны за одну неделю.


2
Вы явно не упомянули, но нужно ли это в порядке убывания?
Ник Т

3
Ты прав, я это пропустил. Все остальные пошли на спуск, поэтому мы будем придерживаться этого.
Hand-E-Food

Я думаю, что окончательное число (21826) было преобразовано неправильно. согласно моему калькулятору Windows, это 0101 0101 0100 0010, а не 0010 1010 1100 0010.
Nzall

Спасибо за эти исправления. Это странно с 21826, потому что я использовал Excel для преобразования чисел в двоичные. Интересно об отдыхе сейчас.
Hand-E-Food

Решение с использованием ассемблера и инструкции popcount?
eiennohito

Ответы:


27

J (11)

(\:+/"1@#:)

Это функция, которая принимает список:

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

Если вы хотите дать ему имя, стоит один дополнительный символ:

     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

Объяснение:

  • \:: сортировать вниз
  • +/: сумма
  • "1: каждый ряд
  • #:: двоичное представление

5
@ ak82 это ASCII-версия APL
Джон Дворак

3
@JanDvorak своего рода; было довольно много изменений: jsoftware.com/papers/j4apl.htm (см. раздел «Язык»).
Джеймс Вуд

3
Там также, \:1#.#:который экономит несколько байтов.
миль

17

JavaScript, 39

Обновление: теперь короче, чем 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)

Объяснение:

q - рекурсивная функция. Если x или y равны 0, возвращается x-y(отрицательное число, если x равно нулю, или положительное число, если y равно нулю). В противном случае он удаляет младший бит ( x&x-1) из x и y и повторяется.

Предыдущая версия (42)

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

Это действительно умно! Я все еще пытаюсь обдумать это.
Mowwwalker

Не должно ~yработать вместо -!y?
Зубная щетка

@toothbrush Конечным условием является то, что x или y равны 0, и в этом случае выражение !x|-!yстановится ненулевым. ~на самом деле не подходит, так как он ненулевой для многих входов (включая ноль)
скопируйте

Может кто - нибудь помочь мне в случае требуется вторичная сортировка , пожалуйста?
Манубхаргав

15

Рубин 41

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

Тест:

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
Просто. Понятный. Короткий. Престижность для этого решения.
Пьер Арло


8

Common Lisp, 35

logcountвозвращает количество «битов» в числе. Для списка lу нас есть:

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

Как отдельная функция, и на чем я буду основывать подсчет байтов:

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

7

Python 3, 90 77 72 67 символов.

Наше решение принимает входные данные из командной строки и печатает число в порядке убывания (67 символов) или в порядке возрастания (66).

В порядке убывания

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

Спасибо @daniero , за предложение использовать минус в числе 1, чтобы повернуть его вспять, вместо того, чтобы использовать ломтик, чтобы повернуть массив в конце! Это эффективно спасло 5 персонажей.

Просто чтобы опубликовать его, версия в порядке возрастания (которая была первой, которую мы сделали) будет занимать на один символ меньше.

Восходящий порядок :

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

Спасибо @Bakuriu за ключ = лямбда-х… предложение. ; D


Так 0что всегда будет частью вашей продукции; Это не правильно.
Даниеро

В этом вопросе я не вижу ничего, что мешало бы мне вводить значение.
Jetlef

Я делаю: «Массив из тех же целых чисел, отсортированных, как описано». ;) Кроме того, почему бы просто не использовать raw_input()и не удалять некоторые символы?
Даниеро

1
@daniero исправил это. Переключение на Python 3 (ответ на Python 2 уже присутствовал, должен быть креативным!) Позволяет мне использовать input () , сохраняя два символа (два должны быть добавлены из-за скобок, требуемых print () ).
Jetlef

Вы можете оставить []внутри sorted. Кроме того, результатом этой программы является число 1 в числах на входе, отсортированных, но вы должны вывести число, которое вы получили на входе, отсортированное по числу 1s. Что-то вроде: print(sorted(input().split(), key=lambda x:bin(int(x)).count('1')))было бы правильно.
Бакуриу

7

JavaScript [76 байт]

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

где aвходной массив чисел.

Тест:

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

Не могли бы вы рассказать, как ..работает? Насколько я понимаю, если x = 5потом eval(x + r)становится eval(5..toString(2).match(/1/g).length)недействительным, я полагаю. Спасибо.
Гауранг Тандон

1
@GaurangTandon Это не так. Как вы знаете, в JS все, кроме литералов, является объектом. И цифры. Таким образом, теоретически (и практически) вы можете получить свойства или вызвать методы любого не-литерального типа с помощью точечной нотации, как вы это делаете 'string'.lengthили [1,2,3].pop(). В случае чисел вы можете сделать то же самое, но вы должны иметь в виду, что после одной точки парсер будет искать дробную часть числа, ожидающего значение с плавающей запятой (как в 123.45). Если вы используете целое число , вы должны «сказать» парсер , что дробная часть пуста, установив дополнительную точку перед адресацию свойства: 123..method().
VisioN

1
Вы можете сохранить два байта, удалив нули и обработав остальные как десятичное число. Заменить match(/1/g).lengthна replace(/0/g,"").
DocMax

@VisioN Спасибо! Узнал новую вещь.
Гауранг Тандон

1
a.sort(function(x,y){r='..toString(2).match(/1/g).length';return eval(y+r+-x+r)})
16м2

6

Mathematica 30

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

Использование:

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

к [15 символов]

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

Пример 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

Пример 2 (все числа 2 ^ n -1)

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

127 63 31 15 7 3

5

Mathematica 39

IntegerDigits[#,2] преобразует число 10 в список 1 и 0.

Tr суммирует цифры.

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

Прецедент

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

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


Я полюбил это (ab?) Использование Tr [] в коде игры в гольф.
Майкл Стерн

5

Java 8 - 87/113 81/111 60/80 60/74/48 символов

Это не полная Java-программа, это просто функция (точнее, метод).

Предполагается, что java.util.Listи java.lang.Long.bitCountимпортируются, и имеет 60 символов:

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

Если никакие предварительно импортированные материалы не разрешены, здесь это с 74 символами:

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

Добавьте еще 7 символов, если это потребуется static.

[4 года спустя] Или, если хотите, это может быть лямбда (спасибо @KevinCruijssen за предложение) с 48 байтами:

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

Любая причина, почему вы не можете сделать Integer.bitCount(x)<Integer.bitCount(y)?-1:1;? Вам нужно -1,0,1поведение?
Джастин

Кроме того, возможно ли заменить <Integer>с пробелом?
Джастин

Вы также можете использовать это Long, чтобы сэкономить место :)
RobAu

Также a.sort((x,y)->Long.bitCount(x)-Long.bitCount(y));
RobAu

1
@KevinCruijssen Спасибо. Я так привык, что использование экземпляра переменной для вызова статического метода - плохая практика, что я когда-либо забывал, что компилятор принимает это.
Виктор Стафуса

4

Python 2.x - 65 символов (байт)

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

Это на самом деле 66 символов, 65, если мы сделаем это функцией (тогда вам нужно что-то, чтобы вызвать это, что ламернее представить).

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

Демо в 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:]))"

Вы можете изменить sum(int(d)for d in bin(x)[2:])наsum(map(int,bin(x)[2:]))
Елисей

1
или даже:print sorted(input(),key=lambda x:-bin(x).count('1'))
Елисей

4

Матлаб, 34

Ввод в «а»

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

Работает для неотрицательных чисел.


4

C - 85 байт (108 106 байт)

Портативная версия на GCC / Clang / везде, где __builtin_popcountесть (106 байт):

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

Ультраконденсированная, непереносимая, едва функциональная версия только для MSVC (85 байт):

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

  • Первая новая строка включена в число байтов из-за #define, остальные не нужны.

  • Функция для вызова в s(array, length)соответствии со спецификациями.

  • Можно жестко закодировать sizeofв переносимой версии, чтобы сохранить еще 7 символов, как это сделали несколько других ответов на языке C. Я не уверен, какой из них стоит больше всего с точки зрения коэффициента полезного использования по длине, вы решаете.


2
sizeof lсохраняет байт. Ужасно уродливый #define p-__builtin_popcount(может помочь спасти другого.
Угорен

@ugoren Спасибо за советы! Препроцессор один такой взломать, я понятия не имел, что такое возможно. К сожалению, это не работает на MSVC, но каждый байт имеет значение!
Томас,

4

PowerShell v3, 61 58 53

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

ScriptBlock для Sort-Objectкомандлета возвращает массив из 1 для каждого 1 в двоичном представлении числа. Sort-Objectсортирует список по длине массива, возвращаемого для каждого числа.

Выполнить:

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

это работает. Как это работает? Как волшебство. приходит к «на основе длины массива»?
Маззи

"." выполняет блок скрипта, который идет после него. Команда sort сортирует на основе выходных данных внешнего блока сценария. Теперь я понимаю, что внутренний скрипт-блок не нужен. см. правку
Rynant

$f={является избыточным, while-> for, -band1-> %2, -des-> -dи другие уловки гольфа. Ясно. Можете ли вы объяснить, как работать $args|sort{@(1,1,...,1)}? Это работает! Как сортировка сравнивает массивы без явного .Count? где почитать об этом? Благодарность!
Маззи

1
@ mazzy, ты прав, теперь я удалил лишние биты. Это сортировка по умолчанию для командлета Sort-Object. Смотрите: help Sort-Object -Parameter propertyя не знаю, где определено свойство сортировки по умолчанию для типов, но для массивов это Count или Length.
Rynant

Хорошая догадка. Но $args|sort{while($_){if($_-band1){$_};$_=$_-shr1}}-desдает неверный результат. Поэтому это не так Count. Это очень интересно. Еще раз спасибо.
Мази

3

ECMAScript 6, 61

Предполагается z, что вход

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

Тестовые данные

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

Спасибо, зубная щетка за более короткое решение.


1
Я только что попробовал ваше решение, но оно не сработало. Это не сортирует числа.
Зубная щетка

@ щетка woops. Спасибо, что поймали это, должно работать сейчас.
Дэнни

Отличная работа! Мне это нравится.
Зубная щетка

1
Всего 61 байт: z.sort((a,b)=>{c=d=e=0;while(++c<32)d+=a>>c&1,e+=b>>c&1},e-d)(и спасибо за голосование).
Зубная щетка

1
Мое решение теперь такого же размера, как ваше!
Зубная щетка

3

R , 132 96 94 88 84 75 73 53 51 байт

-20 благодаря реализации J.Doe - еще 2 благодаря Giuseppe

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

Мой оригинальный пост:

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

Попробуйте онлайн!

Я попробовал несколько разных методов, прежде чем приступить к этому результату.

Матричный метод: создал матрицу из двух столбцов, один столбец с входным вектором, один из суммы двоичного представления, затем я отсортировал по сумме двоичного.

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

Нематричный: понял, что я мог бы выбросить матричную функцию и вместо этого создать вектор двоичных значений, суммировать их, упорядочить их, а затем использовать упорядоченные значения для изменения порядка входного вектора.

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

Небольшие изменения

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

Больше мелких изменений. Преобразование всего в одну строку кода вместо двух, разделенных точкой с запятой.

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

Метод Sum Вместо добавления столбцов с colSumsсозданной двоичной матрицей sapply, я добавил элементы в столбец перед тем, как sapply«закончить».

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

Снижение к Rev I очень хотел сократить уменьшается, но R пронзительных у меня , если я пытаюсь сократить decreasingв orderфункции, которая необходима для того, чтобы получить заказ желательно , как по orderумолчанию для увеличения, то я вспомнил revфункцию обратного вектора. ЭВРИКА !!! Последнее изменение в окончательном решении состояло functionв том, pryr::fчтобы сохранить еще 2 байта

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


1
51 байт улучшается при превосходном гольфе @ J.Doe!
Джузеппе

2

Хаскелл, 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)

Это первый способ решить эту проблему, но я уверен, что есть лучший способ сделать это. Кроме того, если кто-нибудь знает способ игры в гольф на Haskell, мне было бы очень интересно услышать об этом.

пример

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

Неуправляемая версия (с объяснениями)

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)

было бы полезно использовать инфиксное обозначение mod, n`mod`2? Он имеет тот же приоритет, что и умножение и деление.
Джон Дворак

Насколько я понимаю, это было бы не слишком полезно для игры в гольф. Я бы потерял два пробела, но получил бы два кавычки, верно?
danmcardle

import Data.List; import Data.Ord; import Data.Bits; q = sortBy (сравнение popCount) - 80C - или, используя ваш подход, импортируйте Data.List; import Data.Ord; b 0 = 0; bn = (mod n 2) + b (div n 2); q = sortBy (сравнение b) - 86C
bazzargh

Я старался избегать импорта полностью, лучше всего справиться с 87C с помощью быстрой игры в гольф: 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)

Читаемый код (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]

Оптимизировано (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

Обфусцирование (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

Тернарные операторы чрезмерно длинные (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))

Слишком долго, прекрати кастовать (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)

Финал (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 (или, может быть, 24)

ввод в; деструктивно сортирует в:

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

функциональная версия: возвращает новый отсортированный массив:

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

есть даже более короткий вариант (передача имени или функции в качестве аргумента) в 24 символа. Но (вздох) это будет сортировать самое высокое в прошлом. Как я понял, об этом не просили, поэтому я не воспринимаю это как результат игры в гольф:

a sortBySelector:#bitCount

2

PHP 5.4+ 131

Я даже не знаю, почему я беспокоюсь о PHP, в этом случае:

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

Использование:

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

ну, кто-то должен беспокоиться о PHP
Einacio


2

DFSORT (продукт сортировки мэйнфреймов IBM) 288 (в каждой строке исходного текста 72 символа, в первой позиции должен быть пробел)

 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)

Просто для удовольствия и без математики.

Принимает файл (может быть выполнен из программы, которая использовала «массив») с целыми числами. Перед сортировкой он переводит целые числа в биты (в 16-символьном поле). Затем изменяет 0 в битах на ничто. Сортировка по убыванию по результату изменения битов. Создает отсортированный файл только с целыми числами.


2

С

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
Так как это соревнование по коду в гольф, вы должны попытаться сократить свой код.
Timtech

2

C #, 88 89

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

Редактировать: по убыванию добавляет символ.


2

Javascript 84

Вдохновлен другими ответами javascript, но без eval и 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));

Вопрос заключается в коде гольфа, пожалуйста, попробуйте «сыграть в гольф» свой код: удалите ненужные пробелы и постарайтесь сделать свой код как можно меньше. Кроме того, включите количество символов в вашем ответе.
ProgramFOX


2

Постскриптум, 126

Поскольку список значений, по которым мы сортируем, известен заранее и очень ограничен (32), эту задачу можно легко выполнить, даже если нет встроенной функции сортировки, путем выбора подходящих значений для 1..32. (Это O (32n)? Вероятно).

Процедура ожидает массив в стеке и возвращает отсортированный массив.

/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

Или, ритуально лишенный пробелов и читабельности:

/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

Затем, если он сохранен, bits.psего можно использовать так:

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]

Я думаю, что он фактически такой же, как этот Perl (здесь еще нет Perl):

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

Хотя , что , в отличие от Postscript, может быть легко golfed:

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

Постскриптум! Моя первая любовь, мой любимый язык всех времен! Приятно видеть другого верующего в Едином Истинном Языке Программирования.
AJMansfield

2

С - 124 111

Реализовано как метод и используется стандартная библиотека для сортировки. Указатель на массив и размер должны быть переданы в качестве параметров. Это будет работать только в системах с 32-разрядными указателями. В 64-битных системах некоторые символы должны быть потрачены на указание определений указателей.

Отступ для удобства чтения

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

Образец звонка:

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

2

Ява 8: 144

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

В развернутом виде:

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

Как вы можете видеть, это работает путем преобразования в argsa Stream<String>, затем преобразования в a Stream<Integer>со Integer::decodeссылкой на функцию (короче parseIntили или valueOf), а затем сортировки Integer::bitCount, затем помещая его в массив и распечатывая его.

Потоки делают все проще.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.