Справедливо оцінюють значення


23

Завдання

З огляду на вхідний список цілих чисел x 1 … x n , обчисліть список рангів r 1 … r n (перестановка {1… n} ), щоб x r 1  ≤ x r 2  ≤… ≤ x r n . Потім для кожного x i замініть його ранг середнім арифметичним рядами всіх значень у x , рівних x i . (Тобто, коли існує розрив між рівними значеннями в x , досить перерозподілити ранги між усіма ними.) Виведіть модифікований список рангів r ' 1 … r'н .

(Для вигуків статистики: такий рейтинг спостережень використовується в тесті Манна – Вітні U (метод другий, крок 1.))

Приклад

З огляду на вхідний список [3, -6, 3, 3, 14, 3] , перший список рангів буде [2, 1, 3, 4, 6, 5] , який би сортував цей список за [-6, 3, 3, 3, 3, 14] . Потім ранги за всі 3 с у вхідному списку вирівнюються в (2 + 3 + 4 + 5) ÷ 4 = 3,5 . Кінцевий вихід - [3,5, 1, 3,5, 3,5, 6, 3,5] .

Тестові справи

[4, 1, 4] -> [2.5, 1.0, 2.5]
[5, 14, 14, 14, 14, 5, 14] -> [1.5, 5.0, 5.0, 5.0, 5.0, 1.5, 5.0]
[9, 9, -5, -5, 13, -5, 13, 9, 9, 13] -> [5.5, 5.5, 2.0, 2.0, 9.0, 2.0, 9.0, 5.5, 5.5, 9.0]
[13, 16, 2, -5, -5, -5, 13, 16, -5, -5] -> [7.5, 9.5, 6.0, 3.0, 3.0, 3.0, 7.5, 9.5, 3.0, 3.0]

Правила

Це , тому найкоротший код у байтах виграє.


Відповіді:


7

Желе , 10 8 байт

ð_'Ṡ‘S‘H

Збережено 2 байти за допомогою cmpтрюку з відповіді @ xnor .

Спробуйте в Інтернеті! або перевірити всі тестові випадки .

Як це працює

ð_'Ṡ‘S‘H  Main link. Left argument: A (list of values)

ð         Make the chain dyadic, setting the right argument to A.
 _'       Spawned subtraction; compute the matrix of differences.
   Ṡ      Apply the sign function to each difference.
    ‘     Increment.
     S    Sum across columns.
      ‘   Increment.
       H  Halve.

6

Піта, 12

m+l<#dQ.OS/Q

Тестовий сюїт

Для кожного значення це обчислює середнє арифметичне значення [1..frequency]та додає кількість значень менше поточного.

Це працює, тому що для кожного значення ми б обчислили:

(1 / frequency) * sum (i = 1..frequency) i + count_less

яку ми можемо спростити:

(1 / frequency) * [ frequency * (frequency + 1) / 2 + count_less * frequency ]

і знову до:

(frequency + 1) / 2 + count_less

Однак у Pyth було гольфіст обчислити першу суму за допомогою середнього вбудованого, а не іншої формули.


4

Python 2, 51 байт

lambda l:[-~sum(1+cmp(y,x)for x in l)/2.for y in l]

Для кожного елемента y, то cmpвираз дає 2 очка за кожен менше , xі 1 бал за кожен рівний x. Ця сума перераховується в потрібний діапазон, додаючи 1 і вдвічі. 2.Необхідно , щоб уникнути поділу на ціле число.

Python 3, 52 байти

Python 3 не вистачає cmp, що вимагає булевого вираження (+2 байти), але він має поплавковий поділ (-1 байт).

lambda l:[-~sum((y>x)+(y>=x)for x in l)/2for y in l]

3

MATL , 14 байт

7#utG&S&S2XQw)

Спробуйте в Інтернеті! Або перевірити всі тестові випадки (трохи змінена версія коду; кожен результат знаходиться в іншому рядку).

      % Implicit input. Example: [5 14 14 14 14 5 14]
7#u   % Replace each value by a unique, integer label. Example: [1; 2; 2; 2; 2; 1; 2]
t     % Duplicate
G&S   % Push input again. Sort and get indices of the sorting. Example: [1 6 2 3 4 5 7]
&S    % Sort and get the indices, again. This gives the ranks. Example: [1 3 4 5 6 2 7]
2XQ   % Compute mean of ranks for equal values of the integer label. Example: [1.5; 5]
w     % Swap top two elements in stack
)     % Index the means with the integer labels. Example: [1.5; 5; 5; 5; 5; 1.5; 5]
      % Implicit display


3

R, 17 12 байт

Приймає вхід з STDIN виходів у STDOUT. Якщо вихідний гнучкий, то ми можемо канаву cat().

rank(scan())

Досить просто, використовує вбудований ранг, який за замовчуванням визначається середнім рівнем.

В вживанні:

> rank(scan())
1: 5 14 14 14 14 5 14
8: 
Read 7 items
[1] 1.5 5.0 5.0 5.0 5.0 1.5 5.0
> rank(scan())
1: 3 -6 3 3 14 3
7: 
Read 6 items
[1] 3.5 1.0 3.5 3.5 6.0 3.5
> 

Ви можете відмовитись cat(), якщо це залежить від мене. Я не знаю, що таке консенсус громади.
Лінн

@Lynn Спасибі, я буду. Я завжди можу це повернути.
MickyT

2

J, 18 байт

1-:@+1+/"1@:+*@-/~

На основі рішення Денніса за допомогою методу xnor .

Використання прямого підходу вимагає для мене 24 байти .

(i.~~.){](+/%#)/.1+/:@/:

Використання

   f =: 1-:@+1+/"1@:+*@-/~
   f 3 _6 3 3 14 3
3.5 1 3.5 3.5 6 3.5
   f 4 1 4
2.5 1 2.5
   f 5 14 14 14 14 5 14
1.5 5 5 5 5 1.5 5
   f 9 9 _5 _5 13 _5 13 9 9 13
5.5 5.5 2 2 9 2 9 5.5 5.5 9
   f 13 16 2 _5 _5 _5 13 16 _5 _5
7.5 9.5 6 3 3 3 7.5 9.5 3 3


1

APL, 17 символів

(y+.×⍋X)÷+/y←∘.=⍨X

Припустимо, що список зберігається в X .

Пояснення:

Зауважте, що APL оцінює вирази справа наліво. Потім:

  • ∘.=⍨X= X∘.=Xде ∘.=зовнішній виріб, що використовується =як діадична функція. (Там, де ви зазвичай розмножувались. Отже, зовнішній математичний добуток може бути записаний як ∘.×.)
  • Отримана матриця зберігається в yі yбезпосередньо згортається, використовуючи +для отримання вектора кількість рівних об'єктів для кожного рангу (давайте називати його z←+/y).
  • ⍋X повертає ряди X
  • y+.×⍋X дає внутрішній добуток нашої матриці y з цим вектором.
  • Результат ділиться (компонентно) на z.


0

JavaScript (ES6), 49 48 байт

a=>a.map(n=>a.reduce((r,m)=>r+(n>m)+(n>=m),1)/2)

Редагувати: Збережено 1 байт шляхом переформулювання виразу, щоб воно тепер виглядало як відповідь Python 3 @ xnor.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.