Beri peringkat daftar skor dengan "lompati"

8

Diberikan daftar skor (bilangan bulat non-negatif) yang disortir dari yang terhebat hingga yang paling kecil:

[ 10, 10, 6,  6,  4,  0]

Tetapkan setiap skor peringkat integer, dimulai dengan 1 dan naik, sehingga skor yang sama memiliki peringkat yang sama (yaitu mereka diikat):

[ 1, 1, 3, 3, 5, 6 ]

Dalam kasus ikatan, peringkat "dilewati," misalnya karena skor terbesar pertama dan kedua (10 dan 10) diikat, mereka berdua memiliki peringkat 1, dan peringkat 2 "dilewati," sehingga skor terbesar ketiga ( 6) memiliki peringkat 3.

Keluarkan daftar peringkat tidak menurun yang sesuai dengan skor input.

Contohnya

In:  10 10  6  6  4  0
Out:  1  1  3  3  5  6
In:  10  9  8
Out:  1  2  3
In:   0  0  0
Out:  1  1  1
In:  16 15 15 12 11 11 10  9  9  9  8  2  2  2  0
Out:  1  2  2  4  5  5  7  8  8  8 11 12 12 12 15

Memasukkan

Asumsikan semua skor adalah antara 0 dan 1.000 inklusif, dan input tidak akan lebih dari 500 skor. Input dapat dalam format apa pun yang sesuai untuk bahasa pilihan Anda (termasuk tetapi tidak terbatas pada STDIN, argumen untuk suatu fungsi, array yang sudah disimpan dalam variabel, dll.).

Keluaran

Kembali atau toko dalam variabel memerintahkan daftar yang dihasilkan dari jajaran, atau menulis ke stdout dengan cara terbaca-manusia (misalnya 1 2 3, [1,2,3], 1\n2\n3\n, dan { 1, 2, 3 }semua baik-baik saja, 123tidak, karena ingin pembatas). Skor input dapat disimpan / dicetak bersama dengan peringkat output yang sesuai, tetapi itu tidak diperlukan.

Batasan

Anda dapat menggunakan perpustakaan standar apa pun yang ditawarkan bahasa Anda. Celah standar berlaku.

Kondisi menang

Ini adalah , jadi program terkecil (dalam byte) menang. Dalam hal seri, jawaban dengan suara terbanyak menang.

Catatan

Ini didasarkan pada pertanyaan Ruby pada SO yang menghasilkan beberapa jawaban menarik, termasuk yang sangat pendek. Saya mendorong Anda untuk datang dengan solusi Anda sendiri sebelum mencari di sana.

Yordania
sumber
1
Saya pikir ini akan menjadi lebih baik, dan jawaban terlarang lebih baik, jika tidak diprioritaskan, dan pangkat yang diperlukan untuk mempertahankan pesanan asli mereka. Yaitu [10, 4, 6, 0, 6, 10] akan menjadi [1, 5, 3, 6, 3, 1]
Cruncher
Poin yang bagus, @Cruncher; jangan ragu untuk memulai utas baru.
Jordan

Jawaban:

8

J ( 7 6)

EDIT: Oh, tunggu! Tidak perlu menjadi fungsi!

>:i.~y

Terima kasih Tuhan untuk i.~...

>:@:i.~

Atau sebagai fungsi bernama (3 karakter lebih, tetapi tidak berbeda secara fungsional):

f=:>:@:i.~

Jalankan tes:

   f=:>:@:i.~
   f 10 10  6  6  4  0
1 1 3 3 5 6
   f 10  9  8
1 2 3
   f 0  0  0
1 1 1
   f 16 15 15 12 11 11 10  9  9  9  8  2  2  2  0
1 2 2 4 5 5 7 8 8 8 11 12 12 12 15
ɐɔıʇǝɥʇu
sumber
1
Mau berkomentar apa ini?
corsiKa
1
1+i.~adalah jenis kereta yang dapat ditugaskan dan digunakan inline, sehingga dapat digunakan sebagai fungsi tanpa parens kereta yang biasa. Itu 5 karakter. Dan sebagai catatan, @lakukan pekerjaan yang sama seperti @:dalam kasus ini, sehingga Anda bisa menyimpan karakter yang mudah di sana.
algorithmshark
8

T-SQL (40)

SELECT RANK()OVER(ORDER BY B DESC)
FROM @

Asumsikan @adalah tabel yang berisi skor sebagai baris.

tanda
sumber
3

Pyth , 6

m'XYdY

Daftar disimpan di Y untuk memulai. Ini secara fungsional sama dengan solusi 22 karakter ruby: map over d di Y ke indeks d di Y plus 1, lalu cetak.

Contoh:

$ echo "=Y[16 15 15 12 11 11 10 9 9 9 8 2 2 2 0)m'XYdY" | python3 pyth.py

[1, 2, 2, 4, 5, 5, 7, 8, 8, 8, 11, 12, 12, 12, 15]
isaacg
sumber
3

Python (33 karakter)

lambda x:[1+x.index(i)for i in x]

Secara fungsional sama dengan jawaban J saya.

ɐɔıʇǝɥʇu
sumber
Karena input dapat dalam format pilihan Anda, Anda dapat mendeklarasikan array yang akan disimpan xuntuk memulai, dan "output" dengan menyimpan hasilnya dalam sebuah variabel.
isaacg
3

APL, 2 byte

⍳⍨

Dalam ⎕IO←1. Dyadic iota mencari argumen kanannya menjadi argumen kiri. Operator menyalin argumen kanan ke argumen kiri jika operan digunakan secara monadik. Karena itu solusinya hanya mencari posisi masing-masing elemen vektor yang diberikan dalam dirinya sendiri.

Sampel:

    ⍳⍨10 10 6  6  4  0
1 1 3 3 5 6
    ⍳⍨0  0  0 
1 1 1 
    ⍳⍨16 15 15 12 11 11 10  9  9  9  8  2  2  2  0
1 2 2 4 5 5 7 8 8 8 11 12 12 12 15
lstefano
sumber
2

STATA (16)

egen b=rank(c),f

Hasil dalam b.

Asumsikan c adalah variabel dalam dataset yang berisi input.

tanda
sumber
1
Stata dalam kode golf? Yang ini benar-benar membuka sekaleng cacing.
shadowtalker
2

Haskell (31)

f x=succ.(`elemIndexJust`x)<$>x -- Requires the Safe module

Pemakaian:

f [10,10,6,6,4,0] --evaluates to [1,1,3,3,5,6]
recursion.ninja
sumber
solusi saya adalah r l=concat$tail$scanl(\s->map$const$length s+s!!0)[0]$group ldengan 61 karakter
haskeller bangga
juga, solusi pertama Anda tidak bekerja karena pembatasan monomorfisme
haskeller bangga
Pembatasan momoprofisme sialan itu ... Saya membuatnya bekerja di GHCI, tetapi karena itu tidak dapat dikompilasi, saya kira saya harus menghapusnya ...
recursion.ninja
Anda dapat membuatnya kembali sehingga akan berhasil
haskeller bangga
1

Jadi untuk menetapkan garis dasar:

Ruby (38)

Dengan asumsi aadalah array:

r,i=1,0;a.map{|x|i+=1;x==a[i-2]?r:r=i}

(Ini didasarkan pada jawaban falsetru pada utas SO asli dan bukan karya asli saya. Saya tahu ada solusi Ruby yang 22 karakter, tetapi saya ingin melihat seseorang membuat yang lebih pendek daripada itu di Ruby.)

Yordania
sumber
1

JavaScript (E6) 41

Fungsi dengan argumen array, mengembalikan array

F=s=>s.map((n,i)=>p-n?(p=n,r=i+1):r,p=-1)

Tes di konsol Firefox

F([10,10,6,6,4,0])

Output: [1, 1, 3, 3, 5, 6]

F([16, 15, 15, 12, 11, 11, 10, 9, 9, 9, 8, 2, 2, 2, 0])

Output: [1, 2, 2, 4, 5, 5, 7, 8, 8, 8, 11, 12, 12, 12, 15]

edc65
sumber
1

R, 15

dengan input disimpan sebagai vektor x,

rank(-x,T,"mi")
shadowtalker
sumber
1

Powershell (70)

$n=1;$c=0;$l=$a[0];$a|%{if($l-eq$_){$n}else{$n=$c+1;$n}$l=$a[$c];$c++}

Itu hanya 51 karakter jika Anda mengambil tugas variabel di awal, yang membuat saya merasa sedikit kurang memadai.

Asumsikan $ a ditugaskan dan disortir sebagaimana ditentukan oleh masalah. $ n melacak peringkat, $ c hanyalah sebuah penghitung yang bekerja dengan $ l, elemen terakhir diperiksa dalam array.

Jika ada yang bisa saya lakukan untuk meningkatkan ini, saya ingin tahu.

fuandon
sumber
1

Jawa (57)

Menggunakan 'aturan' yang sama dengan Allbeert :

Constant ididefinisikan sebagai int[]larik dan berisi input, zberisi ukuran input. Lainnya, l, c, xdan n, didefinisikan sebagai int.

Cuplikan kode yang tersisa adalah:

l=0;c=1;for(x=0;x<z;x++){n=i[x];i[x]=n==l?c:(c=x+1);l=n;}

Hasilnya adalah dalam array input.

Roy van Rijn
sumber
1

Ruby, 22

Saya belum melihat thread SO tapi saya membayangkan ini adalah apa yang mereka hasilkan.

a.map{|i|a.index(i)+1}

Edit: Ya, itu. Saya ragu mungkin untuk menjadi lebih kecil di Ruby, kecuali jika Anda menganggap Anda mendefinisikannya sebagai metode Array, maka Anda dapat melakukannya dalam 18 karakter dengan

map{|i|index(i)+1)

Tapi tentu saja program lengkap di sekitar potongan itu terlihat seperti

class Array
  def ranks
    map{|i|index(i)+1)
  end
end

p [1, 2, 2, 4, 5, 5, 7, 8, 8, 8, 11, 12, 12, 12, 15].ranks
histokrat
sumber
1

> <> (47)

Tidak terlalu dioptimalkan, hanya menguji air dengan golf pertama saya.

r:1:nr2&>ao$:@=?vr~&:|   
&1+&l3)?^;      >r:nr

Mengasumsikan bahwa input dipopulasi sebelumnya dalam stack, sehingga elemen pertama dari input adalah yang pertama muncul.

Pengujian:

fish.py ranks.fish -v 1 2 3 4 5 6 7 8 9 9 10 10

output

1
1
3
3
5
6
7
8
9
10
11
12
Mike Precup
sumber
1
"
Menguji
1

Clojure, 35

Dengan beberapa interop Java dicampur di:

(fn[l](map #(+ 1(.indexOf l %)) l))

Sesi REPL:

golf> ((fn[l](map #(+ 1(.indexOf l %)) l)) [10 10  6  6  4  0])
(1 1 3 3 5 6)
golf> ((fn[l](map #(+ 1(.indexOf l %)) l)) [16 15 15 12 11 11 10  9  9  9  8  2  2  2  0])
(1 2 2 4 5 5 7 8 8 8 11 12 12 12 15)
YosemiteMark
sumber
0

C - 62

Sebagai cuplikan kode, karena tidak ada persyaratan untuk fungsi atau program lengkap.

Mengasumsikan a, n, j, dan ksudah didefinisikan sebagai int*, int, int, dan intmasing-masing, di mana aadalah array yang berisi input, dan nmengandung panjang input.

Ini gagal untuk input dengan panjang 0, dalam hal ini diperlukan 3 karakter lagi.

printf("1");for(k=j=1;++j<=n;)printf(" %d",*a-*(a+++1)?k=j:k);
Allbeert
sumber