Dość rangowe wartości

23

Zadanie

Biorąc pod uwagę wejściową listę liczb całkowitych x 1 … x n , oblicz listę rang r 1 … r n (permutacja {1… n} ), aby x r 1  ≤ x r 2  ≤… ≤ x r n . Następnie dla każdego x i zamień jego rangę na średnią arytmetyczną rang wszystkich wartości w x, które są równe x i . (To znaczy, ilekroć występuje remis między równymi wartościami w x , dość redystrybuuj rangi między nimi wszystkimi.) Wyprowadzaj zmodyfikowaną listę rang r „ 1 … r”n .

(W przypadku maniaków statystycznych: taki ranking obserwacji stosuje się w teście U Manna – Whitneya (metoda druga, krok 1.)

Przykład

Biorąc pod uwagę listę wejściową [3, -6, 3, 3, 14, 3] , pierwsza lista rang byłaby [2, 1, 3, 4, 6, 5] , co posortowałoby listę na [-6, 3, 3, 3, 3, 14] . Następnie szeregi dla wszystkich 3 s na liście wejść są wyrównywane do (2 + 3 + 4 + 5) ÷ 4 = 3,5 . Ostateczna wydajność wynosi [3,5, 1, 3,5, 3,5, 6, 3,5] .

Przypadki testowe

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

Zasady

To jest , więc wygrywa najkrótszy kod w bajtach.

Lynn
źródło

Odpowiedzi:

7

Galaretka , 10 8 bajtów

ð_'Ṡ‘S‘H

Zaoszczędzono 2 bajty, wykorzystując cmplewę z odpowiedzi @ xnor .

Wypróbuj online! lub zweryfikuj wszystkie przypadki testowe .

Jak to działa

ð_'Ṡ‘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.
Dennis
źródło
6

Pyth, 12

m+l<#dQ.OS/Q

Pakiet testowy

Dla każdej wartości oblicza to średnią arytmetyczną [1..frequency]i dodaje liczbę wartości mniejszą niż bieżąca.

Działa to, ponieważ dla każdej wartości obliczamy:

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

które możemy uprościć:

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

i ponownie do:

(frequency + 1) / 2 + count_less

Jednak w Pyth golfista obliczył pierwsze lato przy użyciu wbudowanej średniej, a nie innej formuły.

FryAmTheEggman
źródło
4

Python 2, 51 bajtów

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

Dla każdego elementu yThe cmpekspresja daje 2 punkty dla każdej mniejszej xi 1 dla każdego punktu równe x. Suma ta jest przeskalowywana do odpowiedniego zakresu przez dodanie 1 i zmniejszenie o połowę. Jest 2.to konieczne, aby uniknąć podziału na liczby całkowite.

Python 3, 52 bajty

Brakuje w Pythonie 3 cmp, wymagając wyrażenia logicznego (+2 bajty), ale ma dzielenie zmiennoprzecinkowe (-1 bajt).

lambda l:[-~sum((y>x)+(y>=x)for x in l)/2for y in l]
xnor
źródło
3

MATL , 14 bajtów

7#utG&S&S2XQw)

Wypróbuj online! Lub zweryfikuj wszystkie przypadki testowe (nieco zmodyfikowana wersja kodu; każdy wynik znajduje się w innej linii).

      % 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
Luis Mendo
źródło
3

R, 17 12 bajtów

Przenosi dane wejściowe z wyjść STDIN do STDOUT. Jeśli wyjście jest elastyczne, możemy porzucić cat().

rank(scan())

Dość proste, wykorzystuje wbudowaną pozycję, która domyślnie ustawia się jako średnia dla remisu.

W użyciu:

> 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
> 
MickyT
źródło
Możesz upuścić cat(), jeśli to zależy ode mnie. Nie wiem jednak, jaki jest konsensus społeczności.
Lynn
@ Lynn Dzięki, że to zrobię. Zawsze mogę to odłożyć.
MickyT
2

J, 18 bajtów

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

Oparty na rozwiązaniu Dennisa z wykorzystaniem metody xnor .

Korzystanie z prostego podejścia wymaga dla mnie 24 bajtów .

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

Stosowanie

   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
mile
źródło
1

Właściwie 18 bajtów

;╗`╝╜"╛-su"£MΣu½`M

Wypróbuj online!

Jest to zasadniczo port xnor w języku Python .

Wyjaśnienie:

;╗`╝╜"╛-su"£MΣu½`M
;╗                  push a copy of input to reg0
  `             `M  for x in input:
   ╝                  push x to reg1
    ╜                 push input from reg0
     "    "£M         for y in input:
      ╛                 push x from reg0
       -s               cmp(y,x) (sgn(y-x))
         u              add 1
             Σu½      sum, add 1, half
Mego
źródło
1

APL, 17 znaków

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

Zakładając, że lista jest przechowywana w X .

Wyjaśnienie:

Zauważ, że APL ocenia wyrażenia od prawej do lewej. Następnie:

  • ∘.=⍨X= X∘.=Xgdzie ∘.=jest produktem zewnętrznym =używanym jako funkcja dyadyczna. (Gdzie normalnie byś się pomnożył. Tak więc matematyczny produkt zewnętrzny można zapisać jako ∘.×.)
  • Powstała macierz jest przechowywana yi yjest bezpośrednio składana za pomocą, +aby dać wektor liczby równych obiektów dla każdej rangi (nazwijmy to z←+/y).
  • ⍋X zwraca szeregi X
  • y+.×⍋X daje iloczyn wewnętrzny naszej macierzy y z tym wektorem.
  • Wynik jest dzielony (pod względem komponentów) przez z.
user2070206
źródło
0

Julia, 30 bajtów

!x=-~sum((x.>x')+(x.>=x'),2)/2

To wykorzystuje podejście z odpowiedzi @ xnor . Julia ma cmp, ale nie wektoryzuje.

Wypróbuj online!

Dennis
źródło
0

JavaScript (ES6), 49 48 bajtów

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

Edycja: Zapisano 1 bajt poprzez przeformułowanie wyrażenia, aby teraz wyglądało jak odpowiedź @ xnor na Python 3.

Neil
źródło