Ранжировать список целых чисел

21

Вам дан непустой список натуральных чисел, например

[6 2 9 7 2 6 5 3 3 4]

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

[3 9 1 2 9 3 5 7 7 6]

Например, самое высокое значение на входе было 9, поэтому оно становится 1(первый ранг). Третье по величине значение 6, так что оба 6становятся 3, и ранг 4полностью пропускается.

правила

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

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

Вы можете использовать любой язык программирования , но учтите, что эти лазейки по умолчанию запрещены.

Это , поэтому самый короткий действительный ответ - измеренный в байтах - выигрывает.

Тестовые случаи

[8] -> [1]
[1 15] -> [2 1]
[18 14 11] -> [1 2 3]
[11 16 14 8] -> [3 1 2 4]
[15 15 15 15 15] -> [1 1 1 1 1]
[10 2 5 4 15 5] -> [2 6 3 5 1 3]
[5 5 10 10 5 11 18] -> [5 5 3 3 5 2 1]
[2 4 9 4 17 9 17 16] -> [8 6 4 6 1 4 1 3]
[11 17 19 17 10 10 15 3 18] -> [6 3 1 3 7 7 5 9 2]
[2 11 4 8 3 3 12 20 4 18] -> [10 4 6 5 8 8 3 1 6 2]
[12 6 10 2 19 19 6 19 8 6 18] -> [5 8 6 11 1 1 8 1 7 8 4]
[5 6 14 19 13 5 19 9 19 9 9 19] -> [11 10 5 1 6 11 1 7 1 7 7 1]
[9 2 12 3 7 11 15 11 6 8 11 17 11] -> [8 13 3 12 10 4 2 4 11 9 4 1 4]
[3 5 15 7 18 5 3 9 11 2 18 1 10 19] -> [11 9 4 8 2 9 11 7 5 13 2 14 6 1]
[6 11 4 19 14 7 13 16 10 12 7 9 7 10 10] -> [14 6 15 1 3 11 4 2 7 5 11 10 11 7 7]
[11 20 11 1 20 16 11 11 4 8 9 7 11 14 10 14] -> [6 1 6 16 1 3 6 6 15 13 12 14 6 4 11 4]
[4 7 15 2 3 2 3 1 14 2 10 4 7 6 11 2 18] -> [9 6 2 13 11 13 11 17 3 13 5 9 6 8 4 13 1]
[5 1 17 7 1 9 3 6 9 7 6 3 2 18 14 4 18 16] -> [12 17 3 8 17 6 14 10 6 8 10 14 16 1 5 13 1 4]
[5 6 8 10 18 13 20 10 7 1 8 19 20 10 10 18 7 2 1] -> [16 15 11 7 4 6 1 7 13 18 11 3 1 7 7 4 13 17 18]
[12 17 8 2 9 7 15 6 19 5 13 16 14 20 10 11 18 4 3 1] -> [9 4 13 19 12 14 6 15 2 16 8 5 7 1 11 10 3 17 18 20]
Мартин Эндер
источник
1
Тесно связаны Разница в том, что этот вызов гарантирует, что входные данные отсортированы, а это означает, что большинство ответов основаны на форме indexOfфункции. Я считаю, что для несортированного ввода есть более короткие альтернативы на многих языках.
Мартин Эндер
Извините, но я считаю, что это слишком близко к ссылке Линн. Различия минимальны: значения усекаются, вы не можете предполагать, что уже отсортированный ввод и половина вывода поменялись местами. Принятый ответ на связанный вопрос почти работает. С минимальными усилиями кто-то может заставить это работать. Таким образом, я считаю, что это дублируется.
Исмаэль Мигель
Я не согласен, это явно не дубликат.
Timtech
Я согласен с Timtech, эта задача проще, но не дубликат.
Tuskiomi

Ответы:

13

Обходной путь в Excel для глупых правил, касающихся входных данных мыши при обмене стеками Code Golf: (WESRRMICGSE) 28 байт

rank(RC[1],r1c1:r1024:c1024)

Ввести список как csv ( 10,23,34,2,) в компилятор после ввода источника. без кавычек, без скобок, запятая.

WESRRMICGSE точно так же, как программирование в Excel, за исключением того, что вы можете опустить начальный знак '=', чтобы сохранить байт. Различие в функциональности происходит из-за того, что WESRRMICGSE будет либо перетаскивать формулу вниз, чтобы автоматически копировать код и предоставлять разные выходные данные с одним целочисленным вводом. если в качестве входных данных указан список, этот список помещается в столбец B (столбец ввода), а формула автоматически выводит лекарство, чтобы соответствовать количеству входных данных. (Например: ввод 34,21,45 «перетянет» формулу вниз на 2 ячейки, в общей сложности на 3 ячейки с формулой).

Изменить: я никогда не ожидал, что этот ответ будет популярным. Вот Это Да!

tuskiomi
источник
21
Название языка немного неприятно ...
Конор О'Брайен
На какие правила вы ссылаетесь и насколько они глупы?
Луис Мендо
3
@ LuisMendo правила, объявленные здесь: meta.codegolf.stackexchange.com/questions/10199/… Я думаю, что это правило глупо, потому что я потратил 5 минут, чтобы написать «переводчика», который точно обходит то, о чем они говорят. Чем больше этот язык может использоваться в задачах, тем глупее становится правило. Я обязательно включу это в ссылку.
Tuskiomi
9

Python 2, 41 байт

lambda l:map(sorted(l+[l])[::-1].index,l)

Для каждого значения найдите его индекс в списке, отсортированном по убыванию. Чтобы наибольшее значение давало 1 вместо 0, мы используем дополнительный элемент «бесконечность» самого списка, так как Python 2 обрабатывает списки как больше, чем числа.

Более прямое решение составляет 42 байта и также работает в Python 3.

lambda l:[1+sum(y<x for x in l)for y in l]

Для каждого элемента подсчитывает количество меньших элементов, добавляя 1 к сдвигу в 1.

XNOR
источник
7

R, 24 25 20 байт

Использует стандартную функцию ранга с помощью метода связей «min» над отрицательным вектором. catдобавил, чтобы вывести его на STDOUT. Сохранено благодаря @Guiseppe

cat(rank(-scan(),,"mi"))

пример

> cat(rank(-scan(),,"mi"))
1: 9 2 12 3 7 11 15 11 6 8 11 17 11
14: 
Read 13 items
8 13 3 12 10 4 2 4 11 9 4 1 4
> 
MickyT
источник
Я думаю, вам нужно обернуть это, catчтобы это была полная программа.
Алекс А.
@AlexA. Мне было интересно об этом. Было бы справедливо сказать, что это функция сама по себе, и в этом случае было rank(-a,,'min')бы нормально , если бы входные данные списка были в векторной форме?
MickyT
В этом случае мы считаем это фрагментом, поскольку предполагается, что переменная уже существует в пространстве имен. Чтобы сделать правильное представление функции вам нужно function(a)rank(-a,,'min').
Алекс А.
может быть сокращено до просто, "mi"а не "min".
Джузеппе
@AlexA. почему его нужно завернуть cat? Если бы подача была function(a)rank(-a,,'mi')такой, то это было бы сочтено достаточным, а результаты программы идентичныrank(-scan(),,'mi')
Mark
4

PowerShell v2 +, 43 41 байт

($a=$args)|%{@($a|sort -d).indexof($_)+1}

Разрабатывается независимо, но я вижу, что это тот же алгоритм, что и в решении Python @ xnor , поэтому / shrug.

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

Для каждого элемента в списке ввода это список sortввода в -dпорядке возрастания, берет .indexOf()текущий элемент и добавляет 1. Обратите внимание на явный массив, приведенный @(...)для учета однозначного ввода. Полученные числа остаются на конвейере и вывод неявен.

Сохранено 2 байта благодаря @Matt!

пример

PS C:\Tools\Scripts\golfing> .\rank-the-integers.ps1 6 2 9 7 2 6 5 3 3 4
3
9
1
2
9
3
5
7
7
6
AdmBorkBork
источник
Есть ли причина sort -dне работает для вас? Это однозначно для меня.
Мэтт
@ Матт Странно. На моем Win8.1 ISE, это заявляет, что -Descendingи -Debugявляется неоднозначным. Но в прямой оболочке на Win8.1 и оболочке и ISE на Win10 все работает нормально. Это будет не первый раз, когда моя конкретная установка Win8.1 будет глупой ...: / / Спасибо за гольф!
AdmBorkBork
Также это не работает для всех тестовых случаев? $args|%{@($args|sort -d).indexof($_)+1}это короче, но у меня не было хорошего взгляда, чтобы знать, работает ли это
Мэтт
@Matt Это не работает, потому что второй $argsфункционирует как вход для блока скрипта цикла {...}, так же, как если бы вы использовали filterили function.
AdmBorkBork
3

Октава, 15 байт

@(x)sum(x<x')+1

Порт моего MATL ответа Октаве. Это также работает в Matlab R2016b.

Код определяет анонимную функцию. Чтобы вызвать его, присвойте его переменной. Попробуйте это в Ideone .

Луис Мендо
источник
3

JavaScript (ES6), 38 36 байт

a=>a.map(e=>a.map(d=>r+=e<d,r=1)&&r)

Редактировать: 2 байта сохранены благодаря @ETHproductions.

Нил
источник
.mapFTW ;-)a=>a.map(e=>a.map(d=>r+=e<d,r=1)&&r)
ETHproductions
3
@ETHproductions Почему вы всегда должны испортить мне веселье?
Нил
2

Желе , 5 байт

<S‘ð€

TryItOnline!

Как?

<S‘ð€ - Main link: listOfValues
   ð  - dyadic chain separation
    € - for each
<     - less than (vectorises) - yields a list of 1s and 0s
 S    - sum - yields number of values the current value is less than (those that beat it)
  ‘   - increment - the place of a value is the number that beat it plus 1.
Джонатан Аллан
источник
Насколько это похоже на код J, который я собирался представить? 1+(+/@:<)"0 1~
датчанин
Выглядит похоже (использует уменьшение до суммы?), Но это ни в коем случае не должно помешать вам опубликовать свой код!
Джонатан Аллан
Я думаю, мне было более интересно, что «разделение диадической цепи» и «для каждого» делают на языке, вдохновленном J.
датчанин
Ах, хорошо из вашего объяснения, я думаю, что ваш код больше похож >€µS‘или действительно похож <@€µS‘( @обращает аргументы к <оператору). J ~является неявным в цепочке слева от µ, которая является монадическим (а не диадическим) разделением и <векторизируется, если аргумент (ы) является (являются) списком (ами).
Джонатан Аллан
2

Perl 6 ,  42  26 байт

Найти первый индекс :kв перевернутом [R,]отсортированном списке

{map {[R,](.sort).first(*==$^a,:k)+1},@$_}

Подсчитайте значения, которые больше, и добавьте одно

{map {1+.grep(*>$^a)},@$_}
Брэд Гилберт b2gills
источник
2

JavaScript, 87 49 байт

f=a=>a.slice().map(function(v){return a.sort(function(a,b){return b-a}).indexOf(v)+1 })

a=>[...a].map(v=>a.sort((a,b)=>b-a).indexOf(v)+1)

Спасибо Конор О'Брайен и ETHproductions!

Оливер
источник
1
Вы можете использовать анонимную функцию в карте, то есть v=>a.sort((a,b)=>b-a).indexOf(v)+1.
Конор О'Брайен
Вам не нужно .slice()вообще, потому что .mapработает с копией массива.
ETHproductions
И наша политика сайта заключается в том, что функция не должна называться по имени, поэтому вы также можете удалить ведущую f=.
Конор О'Брайен
@ETHproductions Если я удаляю ломтик, передавая вместо него [18,13,18]возврат[1,1,2][1, 3, 1]
Оливер
О, это странно ... Я думаю, это потому, что a.sort()хранит отсортированный массив в a. Но вы можете изменить a.slice()это, [...a]чтобы сохранить несколько байтов.
ETHproductions
2

Mathematica, 44 байта 42 байта 40 байтов

xPosition[SortBy[x,-#&],#][[1,1]]&/@x

3-байтовый символ частного использования U+F4A1( страница документации Wolfram )

Изменить: Спасибо JHM за байтовую экономию.

ngenisis
источник
1
Сбой для тестового примера {10,2,5,4,15,5}(выход должен быть {2,6,3,5,1,3}не {2,5,3,4,1,3}. Обратите внимание , что 4должно быть пропущено , потому что есть два 5с во входном).
JungHwan Мин
Правильно исправлено.
ngenisis
1
-2 байт путем переключения xи #(фактически избавившись от скобок): xPosition[SortBy[x,-#&],#][[1,1]]&/@x.
JungHwan Мин
2

J , 14 8 байт

1+1#.</~

Как?

1+1#.</~ - Consumes and returns a list of integers
       ~ - Use the same list for both inputs
     </  - Create a table of less-than comparisons
  1#.    - Treat each row like digits of a base-one number, returning a list of integers
1+       - Increment the results

Предыдущее решение

1+(+/@:<)"0 1~
датчанин
источник
Здравствуйте, я нашел более короткую версию для 8 байтов 1+1#.</~. Строковое суммирование выполняется с использованием преобразования базы 1. Другой альтернативой является 1+\:~i.]также 8 байтов.
миль
Ницца! Вы хотите опубликовать свой ответ? В противном случае я включу улучшение базового уровня.
датчанин
2
Нет, я в порядке с предложением экономии байтов. Не стесняйтесь использовать их
мили
1

Чудо , 28 байт

@(->@+1:0iO#0rev sort#I#1)#0

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

(@(->@+1:0iO#0rev sort#I#1)#0)[6 2 9 7 2 6 5 3 3 4]

Сопоставьте входной массив с функцией, которая добавляет 1 к первому индексу элемента в отсортированной по убыванию версии ввода.

Mama Fun Roll
источник
1

Mathematica, 37 байт

Min@Position[-Sort@-#,i]~Table~{i,#}&

Чистая функция, которая будет оценивать входные данные в соответствии с правилами задачи. Пример:

Min@Position[-Sort@-#, i]~Table~{i, #} &[{6, 2, 9, 7, 2, 6, 5, 3, 3, 4}]
(*{3, 9, 1, 2, 9, 3, 5, 7, 7, 6}*)
Х. Антонио Перес
источник
1

Медуза , 15 байт

p`&& ~i
  >/+`<

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

объяснение

Похоже, пока нет хорошего способа найти индекс значения в списке в Jellyfish, поэтому здесь используется метод подсчета количества значений больше текущего и увеличения результата. Это в основном делается путем создания унарной функции, которая вычисляет это значение для данного элемента.

     `<

Это создает многопоточную версию оператора сравнения, поэтому, если вы передадите ей целое число и список, он вернет список результатов сравнения между этим целым числом и каждым элементом в списке.

     ~i
     `<

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

   & ~i
   /+`<

Здесь, /+сокращение путем сложения, что означает, что это просто функция «суммировать этот список». &составляет это в предыдущую функцию, так что теперь у нас есть унарная функция, которая подсчитывает, сколько значений на входе больше, чем это целое число.

  && ~i
  >/+`<

Мы также составляем функцию приращения на это.

 `&& ~i
  >/+`<

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

p`&& ~i
  >/+`<

Наконец, это печатает результат.

Мартин Эндер
источник
1

мозговой трах, 124 байта

->,[>>>+>,]<[-<+]+[-->[<[<<<<]>>>+>[>[>>]<[[<<+<<]>+>[->>>>]]<+>>>]+[-<<+]->]<[<
<<<]>+.,>>[>[>->+>>]<<[-<<<<]>-]+[->+]+>>>>]

отформатирован:

->
,[>>>+>,]
<[-<+]
+
[
  -->
  [
    <[<<<<]
    >>>+>
    [
      >[>>]
      <
      [
        [<<+<<]
        >+>[->>>>]
      ]
      <+> >>
    ]
    +[-<<+]
    ->
  ]
  <[<<<<]
  >+.,>>
  [
    >[>->+>>]
    <<[-<<<<]
    >-
  ]
  +[->+]
  +>>>>
]

Это разработано для 8-битных реализаций мозгового меха. Вход и выход осуществляются через байтовые значения .

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

Для каждого элемента это число элементов больше его, а затем вывод результата плюс один. Это достигается путем увеличения всех элементов до тех пор, пока текущий элемент не станет равным нулю, обновляя результат всякий раз, когда другой элемент становится равным нулю перед текущим элементом.

Лента разбита на 4-ячеечные узлы,

b c 0 0

где cнаходится элемент иb является флагом навигации, который является отрицательным для текущего элемента, в противном случае - один.

Результат и копия текущего элемента хранятся слева от массива.

Митч Шварц
источник
1

Java, 215 байт

public class G{public static void L(int[]A){int[]r=new int[A.length];for(int i=0;i<A.length;i++){int c=1;for(int j=0;j<A.length;j++){if(A[j]>A[i])c++;}r[i]=c;}for(int i=0;i<r.length;i++)System.out.print(r[i]+",");}}

Объяснение:

Очень само за себя.

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

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

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

Генри
источник
Вы можете удалить часть этого пробела? Поскольку это действительно не игра в гольф вообще. (то есть пробелы в r = new)
Rɪᴋᴇʀ
@EasterlyIrk Да, извините, я не привык к этому. Я думаю, что я избавился от всех ненужных пробелов.
Генри
Можете ли вы назвать "rankNumbersGolf" что-то более короткое, как "G" или что-то?
Rɪᴋᴇʀ
@EasterlyIrk Да, спасибо.
Генри
Я не хорошо Java, но вы можете удалить некоторые пробелы в трех for (?
Rɪᴋᴇʀ
0

PHP, 101 байт

Должен быть какой-то более короткий путь.

function f(&$a){for($r=1;$v++<max($a);$r+=$n,$n=0)foreach($a as$k=>$w)if($w===$v){$a[$k]="$r";$n++;}}

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

Использование: $a=[1,2,4,2,2,3];f($a);print_r($a);

Titus
источник
0

Рубин, 45 40 байт

->a{a.map{|x|a.sort.reverse.index(x)+1}}
Ли В.
источник
Как это называется? Я не могу заставить его соответствовать контрольным случаям, кажется, есть ошибка с равными рангами. Например, [10, 2, 5, 4, 15, 5]дает вывод, [2, 5, 3, 4, 1, 3]когда это должно быть [2, 6, 3, 5, 1, 3]- я думаю, чтобы исправить, что вы просто удалите .uniq- сохранение 5 байтов!
Нил Слэйтер
Кажется, я неправильно понял вопрос. Спасибо, что заметили это!
Ли W
0

Clojure, 48 44 байта

Обновление: использование forвместоmap

#(for[i %](+(count(filter(partial < i)%))1))

Просто фильтрует каждое значение меньше текущего, считает длину списка и увеличивает его на единицу.

NikoNyrh
источник
0

PHP, 84 байта

function r($l){$s=$l;rsort($s);foreach($l as$n)$r[]=array_search($n,$s)+1;return$r;}

Использование: Передайте функции r свой массив целых чисел, и она вернет соответствующий массив ранжированных целых чисел.

Сдача тестов здесь.

Progrock
источник
0

К (ок) , 11 байт

Решение:

1+(x@>x)?x:

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

Примеры:

1+(x@>x)?x:6 2 9 7 2 6 5 3 3 4
3 9 1 2 9 3 5 7 7 6
1+(x@>x)?x:5 6 14 19 13 5 19 9 19 9 9 19
11 10 5 1 6 11 1 7 1 7 7 1

Объяснение:

Найти позицию исходного списка в отсортированном списке, затем добавить один.

1+(x@>x)?x: / the solution
         x: / save input as x
  (  >x)    / return indices of x sorted in descending order
   x@       / apply these indices to x (thus sort x)
        ?   / lookup right in left
1+          / add one
streetster
источник