Fairly rank values
Jelly, 10 8 bytes
ð_'Ṡ‘S‘H
Saved 2 bytes by using the cmp
trick from @xnor's answer.
Try it online! or verify all test cases.
How it works
ð_'Ṡ‘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.
Pyth, 12
m+l<#dQ.OS/Q
Test Suite
For each value this computes the arithmetic mean of [1..frequency]
and adds the count of values less than the current one.
This works because for each value we would compute:
(1 / frequency) * sum (i = 1..frequency) i + count_less
which we can simplify to:
(1 / frequency) * [ frequency * (frequency + 1) / 2 + count_less * frequency ]
and again to:
(frequency + 1) / 2 + count_less
However, in Pyth it was golfier to compute the first summand by using the mean builtin, rather than this other formula.
Python 2, 51 bytes
lambda l:[-~sum(1+cmp(y,x)for x in l)/2.for y in l]
For each element y
, the cmp
expression gives 2 points for each smaller x
and 1 point for each equal x
. This sum is rescaled into the right range by adding 1 and halving. The 2.
is needed to avoid integer division.
Python 3, 52 bytes
Python 3 lacks cmp
, requiring a Boolean expression (+2 bytes), but it has float division (-1 byte).
lambda l:[-~sum((y>x)+(y>=x)for x in l)/2for y in l]