Pokaż pięć najlepszych wyników komentarzy w poście SE

30

Skrypt Stack Exchange określa, które pięć komentarzy na pytania lub odpowiedzi są początkowo widoczne na stronie głównej witryn poprzez liczbę pozytywnych opinii; wyświetlanych jest pięć komentarzy z największą liczbą głosów. Twoim zadaniem jest odtworzenie tego zachowania.

Napisz pełny program lub funkcję, przyjmując dane wejściowe przez STDIN, argumenty wiersza poleceń lub argumenty funkcji i wypisuje lub zwraca pięć pierwszych ocen komentarzy. Dane wejściowe to tablica liczb całkowitych reprezentujących liczbę głosów pozytywnych w komentarzach do niektórych postów. Na przykład wejście

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

oznacza, że ​​pierwszy komentarz nie ma głosów, drugi ma dwa głosy, trzeci ma pięć, czwarty ma cztery itd. Kolejność wyników komentarzy powinna pozostać taka sama w wyniku.

Jeśli dane wejściowe zawierają pięć lub mniej ocen komentarzy, wynik nie powinien zawierać nic więcej niż podane. Jeśli dwie lub więcej ocen jest takich samych, powinny zostać wyświetlone pierwsze oceny. Możesz założyć, że tablica wejściowa będzie zawierać co najmniej jeden wynik komentarza.

Liczby na wyjściu powinny być łatwo rozróżnialne (więc 02541 dla przypadku 1 jest niepoprawne). W przeciwnym razie nie ma ograniczeń dotyczących formatu wyjściowego; liczby mogą być oddzielone spacją lub znakiem nowej linii lub mogą być w formacie listy itp.

Przypadki testowe:

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

Ostatni przykład wzięto z pytania dotyczącego przepełnienia stosu .

Jeśli to możliwe, podaj link w swoim poście, gdzie można przesłać zgłoszenie online.

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

TNT
źródło
Czy musimy zachować porządek?
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ Tak. Kolejność wyświetlania liczb całkowitych nie powinna ulec zmianie.
TNT

Odpowiedzi:

10

Galaretka , 6 bajtów

NỤḣ5Ṣị

Wypróbuj online! lub zweryfikuj wszystkie przypadki testowe jednocześnie .

Jak to działa

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

Python 2, 58 bajtów

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

Przetestuj na Ideone .

Jak to działa

list.removeusuwa pierwsze wystąpienie, jeśli jego argument z określonej listy. Odwracając listę x , zasadniczo osiągamy to, że zamiast tego usuwa ona ostatnie wystąpienie.

Wystarczy więc usuwać komentarz z minimalną liczbą głosów upvotes, dopóki nie zostanie osiągnięta lista nie więcej niż pięciu komentarzy. Następnie ponownie odwracamy listę, aby przywrócić pierwotną kolejność.

Dennis
źródło
9

Pyth, 11 bajtów

_.-_Q<SQ_5

Obliczamy przecięcie wielosetowe input ( Q) z pięcioma największymi elementami w Q(w kolejności, w jakiej się pojawiają Q), a następnie przyjmujemy pierwsze pięć z nich.

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

Wypróbuj tutaj .

lirtosiast
źródło
<5SQjest równoważne z <SQ_5, co oszczędza 1 bajt.
PurkkaKoodari
Nope .
lirtosiast
Ciekawy. Zastanawiam się, dlaczego nie zostało to zaimplementowane, ponieważ b[:-a]... Myślę, że w pewnym momencie mogło tak być.
PurkkaKoodari
5

MATL , 16 bajtów

tn4>?t_FT#S5:)S)

Używa bieżącej wersji (10.2.1) , która jest wcześniejsza niż to wyzwanie.

Wypróbuj online!

Wyjaśnienie

          % 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
źródło
5

JavaScript, 74 65 62 61 bajtów

3 bajty wyłączone dzięki @ user81655. 1 bajt off dzięki @apsillers.

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

oddalony
źródło
5

Python 3, 76

Zaoszczędziłem 9 bajtów dzięki Kevinowi przypominającemu, że mogę nadużywać, jeśli stwierdzenia w liście komp.

Zaoszczędź 5 bajtów dzięki DSM.

W tej chwili dość proste rozwiązanie. Zdobądź 5 najlepszych wyników, a następnie przeanalizuj listę, dodając je do wyniku, gdy je znajdziemy.

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

Oto moje przypadki testowe, jeśli ktoś ich chce:

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

05AB1E , 12 11 bajtów

Kod:

E[Dg6‹#Rß\R

Wyjaśnienie:

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

Wykorzystuje kodowanie CP-1252.

Adnan
źródło
4

CJam, 16 bajtów

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

Nienazwany blok (funkcja), który pobiera tablicę i zwraca tablicę.

Zestaw testowy.

Wyjaśnienie

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

Narzędzia Bash + GNU, 36

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

I / O sformatowane jako listy rozdzielone znakiem nowej linii przez STDIN / STDOUT.

Wypróbuj online.

Cyfrowa trauma
źródło
3

Python, 68 bajtów

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

Przykładowy przebieg.

Bryła wbudowanych. Myślę, że najlepszym sposobem na wyjaśnienie jest przejrzenie przykładu.

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

enumeratezamienia listę w pary indeks / wartość (technicznie rzecz biorąc enumerateobiekt).

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

Pary są najpierw sortowane według największej wartości, zachowując bieżącą kolejność indeksu dla powiązań. To stawia na pierwszym planie najwyżej ocenione komentarze, zerwane wcześniejszym postem. Następnie branych jest pod uwagę 5 najlepszych takich komentarzy.

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

Umieść pięć pierwszych komentarzy z powrotem w kolejności publikowania, a następnie usuń indeksy, zachowując tylko wyniki.

xnor
źródło
3

PowerShell v4, 120 97 bajtów

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

Eksperymentując, znalazłem alternatywne podejście, które oderwało kilka dodatkowych bajtów. Wydaje się jednak, że jest specyficzny dla PowerShell v4 i tego, jak ta wersja obsługuje sortowanie tablicy hashującej - domyślnie wydaje się, że w v4, jeśli wiele Wartości ma tę samą wartość, bierze tę z „niższym” kluczem, ale nie masz gwarancji, że w wersji 3 lub wcześniejszej, nawet jeśli używasz uporządkowanego słowa kluczowego w wersji 3. Nie w pełni sprawdziłem to w stosunku do programu PowerShell v5, aby stwierdzić, czy zachowanie będzie kontynuowane.

Ta wersja tylko dla v4 pobiera dane wejściowe jako $a, a następnie tworzy nową pustą tabelę mieszającą $b. Przechodzimy przez wszystkie elementy wejścia$a|%{...} i do każdej iteracji dodajemy parę klucz / wartość $b(odbywa się to poprzez wstępną inkrementację zmiennej pomocniczej $djako klucza dla każdej iteracji). Następnie sort $bna podstawie Value, następnie ast , następnie przez (czyli klucz), i wreszcie wyjście tylkoselect-l5sortName.Value na południe od otrzymanego hash.

Jeśli wprowadzonych zostanie mniej niż 5 elementów, po prostu posortuje według wartości, wybierze ostatnie pięć (tj. Wszystkie), ponownie posortuje według klucza i wyprowadzi.


Starsze, 120 bajtów, działa we wcześniejszych wersjach

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

Sam algorytm jak Morgan Thrapp za odpowiedź , która jest podobno wskazanie, że wielkie umysły myślą podobnie. :)

Pobiera dane wejściowe, sprawdza, czy liczba elementów jest mniejsza niż lub równa 5, a jeśli tak, wysyła dane wejściowe i wychodzi. W przeciwnym razie tworzymy ArrayList $b(z nadmiernie długą [System.Collections.ArrayList]obsadą) pięciu najlepszych elementów $a. Następnie iterujemy ponad $ai dla każdego elementu, jeśli jest w nim $b, wypisujemy go, a następnie usuwamy z$b środku, wypisujemy (i oto dlaczego musimy użyć ArrayList, ponieważ usuwanie elementów z tablicy nie jest obsługiwaną funkcją w PowerShell, ponieważ są one technicznie naprawione rozmiar).

Wymaga v3 lub wyższej dla -inoperatora. Na odpowiedź, która działa we wcześniejszych wersjach, swap $_-in$bdla $b-contains$_w sumie 126 bajtów .

AdmBorkBork
źródło
2

Haskell, 62 bajty

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

Przykład użycia: 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].

Jak to działa: powiększ każdy element o jego indeks, posortuj malejąco, weź 5 pierwszych elementów, posortuj według indeksu i usuń indeks.

nimi
źródło
2

PHP 5, 107 102

Zaoszczędź 5 bajtów dzięki @WashingtonGuedes

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

Bez golfa

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;
}

Spróbuj.

Samsquanch
źródło
Ponieważ 1 1 5 1 1 5przesłanie powoduje wygenerowanie wyniku 1 5 1 1 5zamiast prawidłowego 1 1 5 1 5.
TNT
Wygląda na to, że zachowuje się inaczej w PHP 7.X, zmień wersję PHP na 5.6 lub niższą.
Samsquanch
Gotcha, nie zauważyłem numeru wersji. :)
TNT
Na początku też nie. Nie jestem pewien, dlaczego to nie zapisuje używanej wersji, a także kodu. Nie jestem również pewien, dlaczego nie działa poprawnie w 7.X.
Samsquanch
@WashingtonGuedes Usunięcie spacji pozwoliło mi zaoszczędzić 5 bajtów, ale nie widzę żadnych niepotrzebnych średników, które nie spowodowałyby błędu?
Samsquanch
0

Rubin, 82 87 89 bajtów

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

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

oryginalne przesłanie - 56 bajtów, ale w niektórych przypadkach testowych kończy się niepowodzeniem i nie obsługuje $ stdin i $ stdout

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

Wyjaśnienie

$><<               # 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
Jan
źródło
Niezły program. Być może jednak będziesz musiał zapytać o to OP. Nie jestem pewien, czy format wejściowy jest w porządku.
Rɪᴋᴇʀ
@RikerW faktycznie zawodzi, gdy istnieje duplikat top # w ostatnim índice, jestem modyfikując go teraz
John
@RikerW jest już naprawiony i obsługuje standardowe wejście i zapisuje na standardowe wyjście.
John
W porządku. Lubię metodę wprowadzania. Chciałem tylko zapytać o to @TNT.
Rɪᴋᴇʀ
0

Java 7, 155 bajtów

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;}

Nieskluczony i kod testowy:

Wypróbuj tutaj.

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()));
    }
}

Wydajność:

[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
źródło
0

Julia, 48 bajtów

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

Wypróbuj online!

Jak to działa

Komentarz c 1 ma wyższy priorytet niż komentarz c 2, jeśli spełniony jest jeden z poniższych warunków:

  • c 1 ma więcej głosów pozytywnych niż c 2 .
  • c 1 i c 2 mają taką samą liczbę głosów pozytywnych, ale c 1 został opublikowany wcześniej.

Określa to całkowitą kolejność komentarzy, a zadaniem jest znalezienie pięciu komentarzy, które mają najwyższy priorytet.

Zamiast sortować komentarze według priorytetu (co zmieni ich kolejność, dla każdego komentarza c liczymy komentarze, które mają większy lub równy priorytet. Zachowujemy c wtedy i tylko wtedy, gdy ta liczba wynosi 5 lub mniej.

Aby częściowo posortować komentarze według liczby głosów pozytywnych, wykonujemy następujące czynności. Niech x będzie wektorem kolumny zawierającym liczbę głosów. Następnie x'transponuje x - tworząc wektor wiersza - i x.<x'tworzy macierz boolowską, która porównuje każdy element x z każdym elementem x T .

Dla x = [0, 2, 5, 4, 0, 1, 0] daje to

<     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

Sumując w wierszach (via sum(...,2)), liczymy liczbę komentarzy, które mają ściśle więcej głosów pozytywnych niż komentarze w tym indeksie.

Dla przykładowego wektora daje to

4
2
0
1
4
3
4

Następnie policzymy liczbę komentarzy o równej liczbie pozytywnych opinii, które zostały opublikowane wcześniej niż ten komentarz. Osiągamy to w następujący sposób.

Najpierw musimy zbudować tabelę równi z x.==x', co compraes elementy x, z elementami x T . Dla naszego przykładowego wektora daje to:

=     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

Następnie wykorzystujemy cumsumdo obliczenia skumulowanych sum każdej kolumny macierzy.

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

diagDiagon ( ) przechowuje liczbę komentarzy, które mają taką samą liczbę głosów upvotes i pojawiają się nie później niż odpowiadający im komentarz.

1
1
1
1
2
1
3

Dodając dwa wytworzone przez nas wektory wierszowe, otrzymujemy priorytety ( 1 jest najwyższy) komentarzy.

5
3
1
2
6
4
7

Komentarze o priorytetach od 1 do 5 powinny być wyświetlane, więc określamy ich indeksy za pomocą find(....<6)i wyszukujemy odpowiednie komentarze za pomocą x[...].

Dennis
źródło
0

Python 3.5, 68 bajtów

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

Brak dopasowania dla mojej odpowiedzi w języku Python 2 , ale tylko trzy bajty dłuższe niż port do Pythona 3 i myślę, że jest wystarczająco inny, aby być interesującym.

I / O ma postać krotek. Przetestować go na repl.it .

Dennis
źródło