Tampilkan Lima Skor Komentar Teratas pada SE Post

30

Skrip Stack Exchange menentukan lima komentar pada pertanyaan atau jawaban yang pada awalnya terlihat di halaman utama situs melalui jumlah upvote pada mereka; lima komentar dengan jumlah suara terbanyak ditampilkan. Tugas Anda adalah menciptakan kembali perilaku ini.

Tulis program lengkap atau fungsi yang mengambil input melalui STDIN, argumen baris perintah, atau argumen fungsi dan mencetak atau mengembalikan lima skor komentar teratas. Input akan berupa array bilangan bulat yang mewakili jumlah upvotes pada komentar beberapa posting. Misalnya, input dari

0, 2, 5, 4, 0, 1, 0

berarti bahwa komentar pertama tidak memiliki suara, yang kedua memiliki dua suara, yang ketiga memiliki lima, keempat memiliki empat, dll. Urutan skor komentar harus tetap sama dalam output.

Jika input berisi lima atau lebih sedikit skor komentar, maka output harus mengandung tidak lebih dari yang diberikan. Jika dua atau lebih skor komentar sama, skor pertama harus ditampilkan. Anda dapat mengasumsikan bahwa array input akan mengandung setidaknya satu skor komentar.

Angka-angka dalam output harus mudah dibedakan (jadi 02541 untuk kasus 1 tidak valid). Kalau tidak, tidak ada batasan pada format output; angka-angka dapat dipisahkan oleh spasi atau baris baru, atau mungkin dalam format daftar, dll.

Kasus uji:

[0, 2, 5, 4, 0, 1, 0] -> [0, 2, 5, 4, 1]
[2, 1, 1, 5, 3, 6] -> [2, 1, 5, 3, 6]
[0, 4, 5] -> [0, 4, 5]
[1, 1, 5, 1, 1, 5] -> [1, 1, 5, 1, 5]
[0, 2, 0, 0, 0, 0, 0, 0] -> [0, 2, 0, 0, 0]
[0, 0, 0, 0, 1, 0, 0, 0, 0] -> [0, 0, 0, 0, 1]
[5, 4, 2, 1, 0, 8, 7, 4, 6, 1, 0, 7] -> [5, 8, 7, 6, 7]
[6, 3, 2, 0, 69, 22, 0, 37, 0, 2, 1, 0, 0, 0, 5, 0, 1, 2, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 2] -> [6, 69, 22, 37, 5]

Contoh terakhir diambil dari pertanyaan Stack Overflow ini .

Jika memungkinkan, harap berikan tautan di pos Anda di mana kiriman Anda dapat dijalankan secara online.

Ini adalah kode golf, jadi kode terpendek dalam byte menang. Semoga berhasil!

TNT
sumber
Haruskah kita mempertahankan pesanan?
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ Ya. Urutan bilangan bulat seharusnya tidak berubah.
TNT

Jawaban:

10

Jelly , 6 byte

NỤḣ5Ṣị

Cobalah online! atau verifikasi semua kasus uji sekaligus .

Bagaimana itu bekerja

NỤḣ5Ṣị    Main link. Input: A (list)

N         Negate (multiply by -1) all elements of A.
 Ụ        Grade the result up.
          This consists in sorting the indices of A by their negated values.
          The first n indices will correspond to the n highest vote counts,
          tie-broken by order of appearance.
  ḣ5      Discard all but the first five items.
    Ṣ     Sort those indices.
          This is to preserve the comments' natural order.
     ị    Retrieve the elements of A at those indices.
Dennis
sumber
10

Python 2, 58 byte

x=input()[::-1]
while x[5:]:x.remove(min(x))
print x[::-1]

Uji di Ideone .

Bagaimana itu bekerja

list.removemenghapus kejadian pertama jika argumennya dari daftar yang ditentukan. Dengan membalik daftar x , kita pada dasarnya mencapai itu menghapus kejadian terakhir sebagai gantinya.

Dengan demikian, cukup untuk terus menghapus komentar dengan jumlah upvotes minimal sampai daftar tidak lebih dari lima komentar tercapai. Setelah itu, kami membalikkan daftar sekali lagi untuk mengembalikan pesanan awal.

Dennis
sumber
9

Pyth, 11 byte

_.-_Q<SQ_5

Kami menghitung persimpangan multiset dari input ( Q) dengan lima elemen terbesar di Q(dalam urutan mereka muncul Q), kemudian mengambil lima pertama dari mereka.

_ .-           Reverse of multiset difference
     _ Q       of reversed Q
     <         with all but last 5 elements of sorted Q
       S Q                   
       _ 5

Coba di sini .

lirtosiast
sumber
<5SQsetara dengan <SQ_5, yang menghemat 1 byte.
PurkkaKoodari
Tidak .
lirtosiast
Menarik. Saya bertanya-tanya mengapa itu tidak dilaksanakan sebagai b[:-a]... Saya pikir itu bahkan mungkin pada titik tertentu.
PurkkaKoodari
5

MATL , 16 byte

tn4>?t_FT#S5:)S)

Ini menggunakan rilis saat ini (10.2.1) , yang lebih awal dari tantangan ini.

Cobalah online!

Penjelasan

          % implicitly get input
t         % duplicate
n         % number of elements
4>?       % if greater than 4...
  t       % duplicate
  _       % unary minus (so that sorting will correspond to descending order)
  FT#S    % sort. Produce the indices of the sorting, not the sorted values
  5:)     % get first 5 indices
  S       % sort those indices, so that they correspond to original order in the input
  )       % index the input with those 5 indices
          % implicitly end if
          % implicitly display
Luis Mendo
sumber
5

JavaScript, 74 65 62 61 byte

Off 3 byte terima kasih @ user81655. 1 byte off terima kasih @apsillers.

f=a=>5 in a?f(a.splice(a.lastIndexOf(Math.min(...a)),1)&&a):a

dihapus
sumber
5

Python 3, 76

Disimpan 9 byte berkat Kevin yang mengingatkan saya bahwa saya dapat menyalahgunakan jika pernyataan dalam daftar comp.

Disimpan 5 byte berkat DSM.

Solusi yang cukup sederhana saat ini. Raih 5 nilai teratas dan kemudian parsing melalui daftar menambahkannya ke hasil saat kami menemukannya.

def f(x):y=sorted(x)[-5:];return[z for z in x if z in y and not y.remove(z)]

Berikut ini adalah kasus pengujian saya jika ada yang menginginkannya:

assert f([0, 2, 5, 4, 0, 1, 0]) == [0, 2, 5, 4, 1]
assert f([2, 1, 1, 5, 3, 6]) == [2, 1, 5, 3, 6]
assert f([0, 4, 5]) == [0, 4, 5]
assert f([0, 2, 0, 0, 0, 0, 0, 0]) == [0, 2, 0, 0, 0]
assert f([0, 0, 0, 0, 1, 0, 0, 0, 0]) == [0, 0, 0, 0, 1]
assert f([5, 4, 2, 1, 0, 8, 7, 4, 6, 1, 0, 7]) == [5, 8, 7, 6, 7]
assert f([6, 3, 2, 0, 69, 22, 0, 37, 0, 2, 1, 0, 0, 0, 5, 0, 1, 2, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 2]) == [6, 69, 22, 37, 5]
Morgan Thrapp
sumber
4

05AB1E , 12 11 byte

Kode:

E[Dg6‹#Rß\R

Penjelasan:

E           # Evaluate input
 [          # Infinite loop
  D         # Duplicate top of the stack
   g        # Get the length
    6‹#     # If smaller than 6, break
       R    # Reverse top of the stack
        ß\  # Extract the smallest item and remove it
          R # Reverse top of the stack
            # Implicit, print the processed array

Menggunakan pengodean CP-1252.

Adnan
sumber
4

CJam, 16 byte

{ee{1=~}$5<$1f=}

Blok tanpa nama (fungsi) yang mengambil array dan mengembalikan array.

Suite uji.

Penjelasan

ee   e# Enumerate the array, pairing each number with its index.
{    e# Sort by...
 1=  e#   The original value of each element.
 ~   e#   Bitwise NOT to sort from largest to smallest.
}$   e# This sort is stable, so the order tied elements is maintained.
5<   e# Discard all but the first five.
$    e# Sort again, this time by indices to recover original order.
1f=  e# Select the values, discarding the indices.
Martin Ender
sumber
3

Utilitas Bash + GNU, 36

nl|sort -nrk2|sed 5q|sort -n|cut -f2

I / O diformat sebagai daftar yang dipisahkan oleh baris baru melalui STDIN / STDOUT.

Cobalah online.

Trauma Digital
sumber
3

Python, 68 byte

lambda l,S=sorted:zip(*S(S(enumerate(l),key=lambda(i,x):-x)[:5]))[1]

Contoh dijalankan.

Benjolan bawaan. Saya pikir cara terbaik untuk menjelaskan adalah dengan menjalankan contoh.

>> l
[5, 4, 2, 1, 0, 8, 7, 4, 6, 1, 0, 7]
>> enumerate(l)
[(0, 5), (1, 4), (2, 2), (3, 1), (4, 0), (5, 8), (6, 7), (7, 4), (8, 6), (9, 1), (10, 0), (11, 7)]

enumeratemengubah daftar menjadi pasangan indeks / nilai (secara teknis sebuah enumerateobjek).

>> sorted(enumerate(l),key=lambda(i,x):-x)
[(5, 8), (6, 7), (11, 7), (8, 6), (0, 5), (1, 4), (7, 4), (2, 2), (3, 1), (9, 1), (4, 0), (10, 0)]
>> sorted(enumerate(l),key=lambda(i,x):-x)[:5]
[(5, 8), (6, 7), (11, 7), (8, 6), (0, 5)]

Pasangan diurutkan berdasarkan nilai terbesar terlebih dahulu, menjaga urutan indeks saat ini untuk ikatan. Ini menempatkan di depan komentar dengan skor tertinggi, tiebroken oleh posting sebelumnya. Kemudian, 5 komentar terbaik diambil.

>> sorted(_)
   [(0, 5), (5, 8), (6, 7), (8, 6), (11, 7)]
>> zip(*sorted(_))[1]
   (5, 8, 7, 6, 7)

Masukkan lima komentar teratas kembali dalam urutan posting, dan kemudian hapus indeks, hanya menyimpan skor.

Tidak
sumber
3

PowerShell v4, 120 97 byte

param($a)$b=@{};$a|%{$b.Add(++$d,$_)};($b.GetEnumerator()|sort Value|select -l 5|sort Name).Value

Bereksperimen di sekitar, saya menemukan pendekatan alternatif yang bermain golf beberapa byte tambahan. Namun, tampaknya khusus untuk PowerShell v4 dan bagaimana versi itu menangani pengurutan hashtable - tampaknya, secara default, bahwa di v4 jika beberapa Nilai memiliki nilai yang sama, dibutuhkan versi dengan Kunci "lebih rendah", tetapi Anda tidak dijamin dalam v3 atau lebih awal, bahkan ketika menggunakan kata kunci yang dipesan di v3. Saya belum sepenuhnya memeriksa ini terhadap PowerShell v5 untuk mengatakan jika perilaku berlanjut.

Versi v4-only ini mengambil input sebagai $a, kemudian membuat hashtable kosong baru $b. Kami mengulangi semua elemen input $a|%{...}dan setiap iterasi menambahkan pasangan kunci / nilai $b(dilakukan dengan pra-penambahan variabel pembantu $dsebagai kunci untuk setiap iterasi). Kemudian kita sort $bberdasarkan Value, maka selectyang -last 5, kemudian sortoleh Name(yaitu, kunci), dan akhirnya hanya output .Values dari hash yang dihasilkan.

Jika kurang dari 5 elemen dimasukkan, itu hanya akan mengurutkan nilai, pilih lima terakhir (yaitu, semuanya), mengurutkan kembali pada kunci, dan output.


Lebih lama, 120 byte, berfungsi di versi sebelumnya

param($a)if($a.Count-le5){$a;exit}[System.Collections.ArrayList]$b=($a|sort)[-5..-1];$a|%{if($_-in$b){$_;$b.Remove($_)}}

Algoritma yang sama dengan jawaban Morgan Thrapp , yang ternyata merupakan indikasi bahwa orang-orang hebat berpikir sama. :)

Mengambil input, memeriksa apakah jumlah item kurang dari atau sama dengan 5, dan jika demikian output input dan keluar. Jika tidak, kami membuat ArrayList $b(dengan para [System.Collections.ArrayList]pemain panjang selangit ) dari lima elemen teratas $a. Kami kemudian mengulangi $adan untuk setiap elemen jika ada di dalam $bkami output dan kemudian menghapusnya$b (dan inilah mengapa kita perlu menggunakan ArrayList, karena menghapus elemen dari Array bukanlah fitur yang didukung di PowerShell, karena mereka secara teknis diperbaiki ukuran).

Membutuhkan v3 atau lebih tinggi untuk -inoperator. Untuk jawaban yang bekerja di versi sebelumnya, pertukaran $_-in$buntuk $b-contains$_untuk total 126 byte .

AdmBorkBork
sumber
2

Haskell, 62 byte

import Data.List
map snd.sort.take 5.sortOn((0-).snd).zip[0..] 

Contoh penggunaan: map snd.sort.take 5.sortOn((0-).snd).zip[0..] $ [5, 4, 2, 1, 0, 8, 7, 4, 6, 1, 0, 7] -> [5,8,7,6,7].

Cara kerjanya: menambah setiap elemen dengan indeksnya, mengurutkan menurun, mengambil 5 elemen pertama, mengurutkan berdasarkan indeks dan menghapus indeks.

nimi
sumber
2

PHP 5, 107 102

Disimpan 5 byte berkat @WashingtonGuedes

function p($s){uasort($s,function($a,$b){return$a<=$b;});$t=array_slice($s,0,5,1);ksort($t);return$t;}

Tidak disatukan

function p($scores) {
    // sort the array from high to low,
    // keeping lower array keys on top of higher
    // array keys
    uasort($scores,function($a, $b){return $a <= $b;});
    // take the top 5
    $top_five = array_slice($scores,0,5,1);
    // sort by the keys
    ksort($top_five);
    return $top_five;
}

Cobalah.

Samsquanch
sumber
Sebab 1 1 5 1 1 5, kiriman Anda menghasilkan output 1 5 1 1 5bukan yang benar 1 1 5 1 5.
TNT
Tampaknya berperilaku berbeda untuk PHP 7.X, alihkan versi PHP ke 5.6 atau lebih rendah.
Samsquanch
Gotcha, tidak memperhatikan nomor versi. :)
TNT
Awalnya saya juga tidak. Saya tidak yakin mengapa itu tidak menyimpan versi apa yang digunakan serta kodenya. Saya juga tidak yakin mengapa itu tidak berfungsi dengan benar pada 7.X.
Samsquanch
@WashingtonGuedes Menghapus spasi menyelamatkan saya 5 byte, tapi saya tidak melihat titik koma yang tidak perlu yang tidak akan membuat kesalahan?
Samsquanch
0

Ruby, 82 87 89 byte

$><<eval($*[0]).map.with_index{|x,i|[i,x]}.sort_by{|x|-x[1]}[0,5].sort.map(&:last)

memanggil: ruby test.rb [1,2,2,3,4,5]

pengiriman asli - 56 byte tetapi gagal pada kasus uji tertentu & tidak mendukung $ stdin dan $ stdout

_.reduce([]){|a,x|a+=_.sort.reverse[0..4]&[x]if !a[4];a}

Penjelasan

$><<               # print to stdout
eval($*[0])        # evals the passed in array in stdin ex: [1,2,3,4]
.map.with_index    # returns an enumerator with indices
{|x,i|[i,x]}       # maps [index,value]
.sort_by{|x|-x[1]} # reverse sorts by the value
[0,5]              # selects the first 5 values
.sort              # sorts item by index (to find the place)
.map{|x|x[1]}      # returns just the values
John
sumber
Program yang bagus. Anda mungkin harus bertanya kepada OP tentang hal itu. Saya tidak yakin format inputnya oke.
Rɪᴋᴇʀ
@RikerW sebenarnya gagal ketika ada # duplikat teratas di indice terakhir, saya memodifikasinya sekarang
John
@RikerW sudah diperbaiki sekarang, dan mendukung stdin dan menulis ke stdout.
John
Baik. Saya suka metode inputnya. Saya hanya mengatakan untuk bertanya kepada @TNT tentang hal itu.
Rɪᴋᴇʀ
0

Java 7, 155 byte

import java.util.*;List c(int[]f){LinkedList c=new LinkedList();for(int i:f)c.add(i);while(c.size()>5)c.removeLastOccurrence(Collections.min(c));return c;}

Tidak digabungkan & kode uji:

Coba di sini.

import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

class Main{
    static List c(int[] f){
        LinkedList c = new LinkedList();
        for (int i : f){
            c.add(i);
        }
        while(c.size() > 5){
            c.removeLastOccurrence(Collections.min(c));
        }
        return c;
    }

    public static void main(String[] a){
        System.out.println(Arrays.toString(c(new int[]{ 0, 2, 5, 4, 0, 1, 0 }).toArray()));
        System.out.println(Arrays.toString(c(new int[]{ 2, 1, 1, 5, 3, 6 }).toArray()));
        System.out.println(Arrays.toString(c(new int[]{ 0, 4, 5 }).toArray()));
        System.out.println(Arrays.toString(c(new int[]{ 1, 1, 5, 1, 1, 5 }).toArray()));
        System.out.println(Arrays.toString(c(new int[]{ 0, 2, 0, 0, 0, 0, 0, 0 }).toArray()));
        System.out.println(Arrays.toString(c(new int[]{ 0, 0, 0, 0, 1, 0, 0, 0, 0 }).toArray()));
        System.out.println(Arrays.toString(c(new int[]{ 6, 3, 2, 0, 69, 22, 0, 37, 0, 2, 1, 0, 0, 0, 5, 0, 1, 2, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 2 }).toArray()));
    }
}

Keluaran:

[0, 2, 5, 4, 1]
[2, 1, 5, 3, 6]
[0, 4, 5]
[1, 1, 5, 1, 5]
[0, 2, 0, 0, 0]
[0, 0, 0, 0, 1]
[6, 69, 22, 37, 5]
Kevin Cruijssen
sumber
0

Julia, 48 byte

!x=x[find(sum(x.<x',2)+diag(cumsum(x.==x')).<6)]

Cobalah online!

Bagaimana itu bekerja

Komentar c 1 memiliki prioritas lebih tinggi daripada komentar c 2 jika salah satu dari berikut ini benar:

  • c 1 memiliki lebih banyak upvotes daripada c 2 .
  • c 1 dan c 2 memiliki jumlah upvote yang sama, tetapi c 1 telah diposting sebelumnya.

Ini mendefinisikan urutan total komentar, dan tugas yang ada adalah menemukan lima komentar yang memiliki prioritas tertinggi.

Alih-alih mengurutkan komentar berdasarkan prioritas (yang akan mengubah urutannya, untuk setiap komentar c , kami menghitung komentar yang memiliki prioritas lebih besar atau sama. Kami tetap c jika dan hanya jika jumlah ini adalah 5 atau kurang.

Untuk mengurutkan komentar berdasarkan jumlah unduhan, kami melakukan hal berikut. Biarkan x menjadi vektor kolom yang berisi jumlah suara. Kemudian x'mentransposisi x - sehingga menciptakan vektor baris - dan x.<x'membuat matriks Boolean yang membandingkan setiap elemen x dengan setiap elemen x T .

Untuk x = [0, 2, 5, 4, 0, 1, 0] , ini memberi

<     0      2      5      4      0      1      0
0 false   true   true   true  false   true  false
2 false  false   true   true  false  false  false
5 false  false  false  false  false  false  false
4 false  false   true  false  false  false  false
0 false   true   true   true  false   true  false
1 false   true   true   true  false  false  false
0 false   true   true   true  false   true  false

Dengan menjumlahkan seluruh baris (via sum(...,2)), kami menghitung jumlah komentar yang benar-benar lebih banyak upvotes daripada komentar pada indeks itu.

Sebagai contoh vektor, ini memberi

4
2
0
1
4
3
4

Selanjutnya, kami menghitung jumlah komentar dengan jumlah upvotes yang sama telah diposting lebih awal dari komentar itu. Kami mencapai ini sebagai berikut.

Pertama kita membangun sebuah tabel kesetaraan dengan x.==x'yang compraes elemen x dengan unsur-unsur x T . Sebagai contoh vektor kita, ini memberikan:

=     0      2      5      4      0      1      0
0  true  false  false  false   true  false   true
2 false   true  false  false  false  false  false
5 false  false   true  false  false  false  false
4 false  false  false   true  false  false  false
0  true  false  false  false   true  false   true
1 false  false  false  false  false   true  false
0  true  false  false  false   true  false   true

Selanjutnya, kita gunakan cumsumuntuk menghitung jumlah kumulatif dari setiap kolom dari matriks.

1  0  0  0  1  0  1
1  1  0  0  1  0  1
1  1  1  0  1  0  1
1  1  1  1  1  0  1
2  1  1  1  2  0  2
2  1  1  1  2  1  2
3  1  1  1  3  1  3

Diagonal ( diag) memiliki jumlah komentar yang memiliki jumlah upvotes yang sama dan muncul paling lambat dari komentar yang sesuai.

1
1
1
1
2
1
3

Dengan menambahkan dua vektor baris yang kami hasilkan, kami memperoleh prioritas ( 1 adalah yang tertinggi) dari komentar.

5
3
1
2
6
4
7

Komentar dengan prioritas mulai dari 1 hingga 5 harus ditampilkan, jadi kami menentukan indeksnya dengan find(....<6)dan mengambil komentar yang sesuai dengannya x[...].

Dennis
sumber
0

Python 3.5, 68 byte

f=lambda x,*h:x and x[:sum(t>x[0]for t in x+h)<5]+f(x[1:],*h,x[0]+1)

Tidak cocok dengan jawaban Python 2 saya , tetapi hanya tiga byte lebih panjang dari port ke Python 3, dan saya pikir itu cukup berbeda untuk menjadi menarik.

I / O dalam bentuk tuple. Mengujinya pada repl.it .

Dennis
sumber