Nilai peringkat yang adil

23

Tugas

Diberikan daftar input bilangan bulat x 1 ... x n , hitung daftar peringkat r 1 ... r n (permutasi dari {1 ... n} ) sehingga x r 1  ≤ x r 2  ≤ ... ≤ x r n . Kemudian, untuk setiap x i , ganti pangkatnya dengan rata-rata aritmatika dari semua nilai dalam x yang sama dengan x i . (Yaitu, setiap kali ada ikatan antara nilai yang sama dalam x , cukup mendistribusikan ulang peringkat di antara mereka semua.) Keluarkan daftar peringkat yang dimodifikasi r ' 1 ... r'n .

(Untuk geeks statistik: peringkat pengamatan seperti itu digunakan dalam uji Mann-Whitney U (metode dua, langkah 1.))

Contoh

Diberikan daftar input [3, -6, 3, 3, 14, 3] , daftar peringkat pertama adalah [2, 1, 3, 4, 6, 5] , yang akan mengurutkan daftar menjadi [-6, 3, 3, 3, 3, 14] . Kemudian, peringkat untuk semua 3 detik dalam daftar input disamakan menjadi (2 + 3 + 4 + 5) ÷ 4 = 3.5 . Output akhir adalah [3.5, 1, 3.5, 3.5, 6, 3.5] .

Uji kasus

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

Aturan

Ini adalah , jadi kode terpendek dalam byte menang.

Lynn
sumber

Jawaban:

7

Jelly , 10 8 byte

ð_'Ṡ‘S‘H

Disimpan 2 byte dengan menggunakan cmptrik dari jawaban xnor .

Cobalah online! atau verifikasi semua kasus uji .

Bagaimana itu bekerja

ð_'Ṡ‘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
sumber
6

Pyth, 12

m+l<#dQ.OS/Q

Test Suite

Untuk setiap nilai ini menghitung rata-rata aritmatika dari [1..frequency] dan menambahkan jumlah nilai kurang dari yang sekarang.

Ini berfungsi karena untuk setiap nilai kami akan menghitung:

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

yang dapat kita sederhanakan menjadi:

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

dan lagi ke:

(frequency + 1) / 2 + count_less

Namun, di Pyth, pemain golf menghitung puncak pertama dengan menggunakan mean builtin, daripada formula lainnya ini.

FryAmTheEggman
sumber
4

Python 2, 51 byte

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

Untuk setiap elemen y, cmpekspresi memberikan 2 poin untuk masing-masing lebih kecil xdan 1 poin untuk masing-masing sama x. Jumlah ini diubah kembali ke kisaran yang tepat dengan menambahkan 1 dan membagi dua. The 2.diperlukan untuk menghindari pembagian integer.

Python 3, 52 byte

Python 3 tidak memiliki cmp, membutuhkan ekspresi Boolean (+2 byte), tetapi memiliki divisi float (-1 byte).

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

MATL , 14 byte

7#utG&S&S2XQw)

Cobalah online! Atau verifikasi semua kasus uji (versi kode yang sedikit dimodifikasi; setiap hasil berada pada baris yang berbeda).

      % 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
sumber
3

R, 17 12 byte

Membawa input dari output STDIN ke STDOUT. Jika output fleksibel maka kita dapat membuang cat().

rank(scan())

Cukup sederhana, menggunakan peringkat bawaan yang standarnya rata-rata untuk pemutus dasi.

Digunakan:

> 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
sumber
Anda dapat menjatuhkan cat(), jika terserah saya. Saya tidak tahu apa konsensus komunitas itu.
Lynn
@ Lynn Terima kasih saya akan. Saya selalu bisa mengembalikannya.
MickyT
2

J, 18 byte

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

Berdasarkan solusi Dennis menggunakan metode xnor .

Menggunakan pendekatan lurus ke depan membutuhkan 24 byte untuk saya.

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

Pemakaian

   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
mil
sumber
1

Sebenarnya, 18 byte

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

Cobalah online!

Ini pada dasarnya adalah port dari solusi Python xnor .

Penjelasan:

;╗`╝╜"╛-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
sumber
1

APL, 17 karakter

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

Dengan asumsi daftar disimpan di X.

Penjelasan:

Perhatikan bahwa APL mengevaluasi ekspresi dari kanan ke kiri. Kemudian:

  • ∘.=⍨X= di X∘.=Xmana ∘.=produk luar menggunakan =fungsi diad. (Di mana Anda biasanya akan multiply. Jadi produk luar matematika dapat ditulis sebagai ∘.×.)
  • Matriks yang dihasilkan disimpan dalam ydan ylangsung dilipat menggunakan +untuk memberikan vektor dari jumlah objek yang sama untuk setiap peringkat (sebut saja z←+/y).
  • ⍋X mengembalikan jajaran X
  • y+.×⍋X memberikan produk dalam matriks y kami dengan vektor ini.
  • Hasilnya dibagi (komponen bijaksana) oleh z.
pengguna2070206
sumber
0

Julia, 30 byte

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

Ini menggunakan pendekatan dari jawaban @ xnor . Julia punya cmp, tetapi itu tidak membuat vektor.

Cobalah online!

Dennis
sumber
0

JavaScript (ES6), 49 48 byte

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

Sunting: Disimpan 1 byte dengan memformulasikan ulang ekspresi sehingga sekarang sepertinya @ xnor jawaban Python 3.

Neil
sumber