Zeigen Sie die fünf besten Kommentarbewertungen für einen SE-Beitrag

30

Ein Stack Exchange-Skript bestimmt, welche fünf Kommentare zu Fragen oder Antworten anfangs auf der Hauptseite von Websites angezeigt werden, und zwar anhand der Anzahl der Upvotes. Die fünf Kommentare mit der höchsten Stimmenzahl werden angezeigt. Ihre Aufgabe ist es, dieses Verhalten wiederherzustellen.

Schreiben Sie ein vollständiges Programm oder eine Funktion, die Eingaben über STDIN, Befehlszeilenargumente oder Funktionsargumente vornimmt, und geben Sie die ersten fünf Kommentarpunkte aus oder geben Sie sie zurück. Die Eingabe besteht aus einer Reihe von Ganzzahlen, die die Anzahl der Aufwärtsbewertungen für die Kommentare einiger Posts darstellen. Zum Beispiel eine Eingabe von

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

bedeutet, dass der erste Kommentar keine Stimmen hat, der zweite zwei Stimmen hat, der dritte fünf, der vierte vier, usw. Die Reihenfolge der Kommentarbewertungen sollte in der Ausgabe gleich bleiben.

Wenn die Eingabe fünf oder weniger Kommentarbewertungen enthält, sollte die Ausgabe nur die angegebenen Werte enthalten. Wenn zwei oder mehr Kommentarbewertungen gleich sind, sollten die ersten Bewertungen angezeigt werden. Sie können davon ausgehen, dass das Eingabearray mindestens eine Kommentarpunktzahl enthält.

Die Zahlen in der Ausgabe sollten leicht zu unterscheiden sein (daher ist 02541 für Fall 1 ungültig). Ansonsten gibt es keine Einschränkungen für das Ausgabeformat. Die Nummern können durch ein Leerzeichen oder einen Zeilenumbruch getrennt sein, oder sie können im Listenformat usw. sein.

Testfälle:

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

Das letzte Beispiel stammt aus dieser Stapelüberlauf-Frage .

Wenn möglich, geben Sie in Ihrem Beitrag einen Link an, über den Ihre Einreichung online geschaltet werden kann.

Dies ist Codegolf, also gewinnt der kürzeste Code in Bytes. Viel Glück!

TNT
quelle
Müssen wir die Ordnung behalten?
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ Ja. Die Reihenfolge, in der die Ganzzahlen angezeigt werden, sollte sich nicht ändern.
TNT

Antworten:

10

Gelee , 6 Bytes

NỤḣ5Ṣị

Probieren Sie es online! oder überprüfen Sie alle Testfälle auf einmal .

Wie es funktioniert

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
quelle
10

Python 2, 58 Bytes

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

Teste es auf Ideone .

Wie es funktioniert

list.removeEntfernt das erste Vorkommen, wenn sein Argument aus der angegebenen Liste. Durch Umkehren der Liste x wird im Wesentlichen erreicht, dass stattdessen das letzte Vorkommen entfernt wird.

Daher reicht es aus, den Kommentar mit der minimalen Anzahl von positiven Stimmen zu entfernen, bis eine Liste von nicht mehr als fünf Kommentaren erreicht ist. Danach kehren wir die Liste noch einmal um, um die ursprüngliche Reihenfolge wiederherzustellen.

Dennis
quelle
9

Pyth, 11 Bytes

_.-_Q<SQ_5

Wir berechnen den Multiset-Schnittpunkt der Eingabe ( Q) mit den fünf größten Elementen in Q(in der Reihenfolge, in der sie erscheinen Q) und nehmen dann die ersten fünf davon.

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

Probieren Sie es hier aus .

Lirtosiast
quelle
<5SQentspricht <SQ_5, was 1 Byte spart.
PurkkaKoodari
Nein .
Lirtosiast
Interessant. Ich frage mich, warum es nicht implementiert wurde als b[:-a]... Ich denke, es könnte sogar irgendwann so gewesen sein.
PurkkaKoodari
5

MATL , 16 Bytes

tn4>?t_FT#S5:)S)

Hierbei wird die aktuelle Version (10.2.1) verwendet , die älter als diese Herausforderung ist.

Probieren Sie es online!

Erläuterung

          % 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
quelle
5

JavaScript, 74 65 62 61 Bytes

3 Bytes weg danke @ user81655. 1 Byte weg danke @apsillers.

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

entfernt
quelle
5

Python 3, 76

9 Bytes gespart dank Kevin, der mich daran erinnert, dass ich missbrauchen kann, wenn Anweisungen in einer Liste comp.

5 Bytes gespart dank DSM.

Ziemlich einfache Lösung jetzt. Holen Sie sich die 5 besten Ergebnisse und analysieren Sie die Liste. Fügen Sie sie dem Ergebnis hinzu, sobald wir sie finden.

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

Hier sind meine Testfälle, wenn jemand sie haben möchte:

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
quelle
4

05AB1E , 12 11 Bytes

Code:

E[Dg6‹#Rß\R

Erläuterung:

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

Verwendet CP-1252-Codierung.

Adnan
quelle
4

CJam, 16 Bytes

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

Ein unbenannter Block (Funktion), der ein Array aufnimmt und ein Array zurückgibt.

Testsuite.

Erläuterung

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
quelle
3

Bash + GNU-Dienstprogramme, 36

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

E / A-Formatierung als durch Zeilenumbrüche getrennte Listen über STDIN / STDOUT.

Probieren Sie es online aus.

Digitales Trauma
quelle
3

Python, 68 Bytes

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

Beispiellauf.

Ein Klumpen von Einbauten. Ich denke, der beste Weg, dies zu erklären, besteht darin, ein Beispiel durchzuarbeiten.

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

enumerateverwandelt die Liste in Index / Wert-Paare (technisch gesehen ein enumerateObjekt).

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

Die Paare werden zuerst nach dem größten Wert sortiert, wobei die aktuelle Indexreihenfolge für Verbindungen beibehalten wird. Dies bringt die am höchsten bewerteten Kommentare an die Spitze, die von früheren Beiträgen gebrochen wurden. Dann werden die 5 besten solcher Kommentare genommen.

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

Ordnen Sie die ersten fünf Kommentare wieder in der Reihenfolge der Veröffentlichung an, und entfernen Sie dann die Indizes, wobei nur die Ergebnisse beibehalten werden.

xnor
quelle
3

PowerShell v4, 120 - 97 Byte

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

Beim herumexperimentieren habe ich einen alternativen Ansatz gefunden, der einige zusätzliche Bytes abbaut. Es scheint jedoch spezifisch für PowerShell v4 zu sein und wie diese Version die Sortierung einer Hashtabelle handhabt. Wenn in v4 mehrere Werte denselben Wert haben, wird standardmäßig der mit einem "niedrigeren" Schlüssel verwendet, jedoch nicht Sie können nicht garantieren, dass dies in Version 3 oder früher der Fall ist, auch wenn Sie die bestellte Version verwenden Schlüsselwort in Version 3 verwendet wird. Ich habe dies nicht vollständig gegen PowerShell v5 überprüft, um zu sagen, ob das Verhalten weiterhin besteht.

Diese Nur-v4-Version nimmt Eingaben als an $aund erstellt dann eine neue leere Hashtabelle $b. Wir durchlaufen alle Elemente der Eingabe $a|%{...}und fügen jeder Iteration ein Schlüssel / Wert-Paar hinzu $b(dies erfolgt durch Vorinkrementieren einer Hilfsvariablen $dals Schlüssel für jede Iteration). Dann haben wir sort $bbasierend auf Value, dann selectder -last 5, dann sortdurch Name(dh die Schlüssel) und schließlich Ausgabe nur die.Value s des resultierenden Hash.

Wenn weniger als 5 Elemente eingegeben werden, wird nur nach Wert sortiert, die letzten fünf (dh alle) ausgewählt, nach Schlüssel neu sortiert und ausgegeben.


Ältere, 120 Byte, funktioniert in früheren Versionen

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

Gleicher Algorithmus wie die Antwort von Morgan Thrapp , was anscheinend ein Hinweis darauf ist, dass große Köpfe gleich denken. :)

Übernimmt die Eingabe, prüft, ob die Anzahl der Elemente kleiner oder gleich 5 ist, und gibt in diesem Fall die Ein- und Ausgänge aus. Andernfalls erstellen wir eine ArrayList $b(mit der übermäßig langen [System.Collections.ArrayList]Besetzung) der fünf obersten Elemente von $a. Wir durchlaufen dann $ajedes Element und geben es für jedes Element aus, sofern es $bdarin enthalten ist, und entfernen es dann aus$b in der PowerShell befindet, geben (und aus diesem Grund müssen wir ArrayList verwenden, da das Entfernen von Elementen aus einer Array-Struktur in PowerShell technisch nicht unterstützt wird Größe).

Benötigt v3 oder höher für den -inBediener. Wechseln Sie $_-in$bfür eine Antwort, die in früheren Versionen funktioniert, $b-contains$_für insgesamt 126 Byte .

AdmBorkBork
quelle
2

Haskell, 62 Bytes

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

Anwendungsbeispiel: 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].

So funktioniert es: Jedes Element mit seinem Index erweitern, absteigend sortieren, die ersten 5 Elemente nehmen, nach Index sortieren und den Index entfernen.

nimi
quelle
2

PHP 5, 107 102

5 Bytes gespart dank @WashingtonGuedes

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

Ungolfed

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

Versuch es.

Samsquanch
quelle
Denn 1 1 5 1 1 5Ihre Eingabe erzeugt eine Ausgabe von 1 5 1 1 5anstelle der richtigen 1 1 5 1 5.
TNT
Es scheint sich für PHP 7.X anders zu verhalten, wechseln Sie die PHP-Version auf 5.6 oder niedriger.
Samsquanch
Gotcha, habe die Versionsnummer nicht bemerkt. :)
TNT
Anfangs auch nicht. Ich bin mir nicht sicher, warum das nicht die verwendete Version und den Code speichert. Ich bin mir auch nicht sicher, warum es unter 7.X nicht richtig funktioniert.
Samsquanch
@WashingtonGuedes Durch das Entfernen von Leerzeichen wurden 5 Byte gespart, aber es werden keine unnötigen Semikolons angezeigt, die keinen Fehler auslösen würden.
Samsquanch
0

Ruby, 82 87 89 Bytes

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

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

ursprüngliche Einreichung - 56 Bytes, schlägt jedoch in bestimmten Testfällen fehl und unterstützte $ stdin und $ stdout nicht

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

Erläuterung

$><<               # 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
quelle
Nettes Programm. Möglicherweise müssen Sie das OP danach fragen. Ich bin nicht sicher, ob das Eingabeformat in Ordnung ist.
29.
@RikerW es schlägt tatsächlich fehl, wenn es ein doppeltes top # im letzten Index gibt, ich
John
@ RikerW ist jetzt behoben, und es unterstützt stdin und schreibt nach stdout.
John
Okay. Ich mag die Eingabemethode. Ich wollte nur @TNT danach fragen.
29.
0

Java 7, 155 Bytes

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

Ungolfed & Testcode:

Probieren Sie es hier aus.

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

Ausgabe:

[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
quelle
0

Julia, 48 Bytes

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

Probieren Sie es online!

Wie es funktioniert

Der Kommentar c 1 hat höhere Priorität als der Kommentar c 2, wenn eine der folgenden Aussagen zutrifft:

  • c 1 hat mehr positive Stimmen als c 2 .
  • c 1 und c 2 haben die gleiche Anzahl von Upvotes, aber c 1 wurde früher gepostet.

Dies definiert eine Gesamtreihenfolge der Kommentare, und die Aufgabe besteht darin, die fünf Kommentare mit den höchsten Prioritäten zu finden.

Anstatt die Kommentare nach Priorität zu sortieren (was ihre Reihenfolge ändern würde , zählen wir für jeden Kommentar c die Kommentare, die eine höhere oder gleiche Priorität haben. Wir behalten c genau dann bei, wenn diese Anzahl 5 oder weniger beträgt .

Um die Kommentare teilweise nach Anzahl der Upvotes zu sortieren, gehen wir wie folgt vor. Sei x der Spaltenvektor, der die Stimmenanzahl enthält. Dann x'transponiert x - wodurch ein Zeilenvektor erzeugt wird - und x.<x'erzeugt eine Boolesche Matrix, die jedes Element von x mit jedem Element von x T vergleicht .

Für x = [0, 2, 5, 4, 0, 1, 0] ergibt sich

<     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

Durch Summieren über Zeilen (Via sum(...,2)) wird die Anzahl der Kommentare gezählt, die strikt höher bewertet sind als der Kommentar an diesem Index.

Für den Beispielvektor ergibt dies

4
2
0
1
4
3
4

Als nächstes zählen wir die Anzahl der Kommentare, bei denen die gleiche Anzahl von Upvotes früher als dieser Kommentar gepostet wurde. Dies erreichen wir wie folgt.

Zuerst erstellen wir eine Gleichheitstabelle mit x.==x', die die Elemente von x mit den Elementen von x T zusammensetzt . Für unseren Beispielvektor ergibt dies:

=     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

Als nächstes cumsumberechnen wir die kumulativen Summen der einzelnen Spalten der Matrix.

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

Die Diagonale ( diag) enthält die Anzahl der Kommentare, die die gleiche Anzahl von positiven Stimmen haben und nicht später als der entsprechende Kommentar erscheinen.

1
1
1
1
2
1
3

Durch Addition der beiden erzeugten Zeilenvektoren erhalten wir die Prioritäten ( 1 ist die höchste) der Kommentare.

5
3
1
2
6
4
7

Kommentare mit Prioritäten von 1 bis 5 sollten angezeigt werden, daher ermitteln wir ihre Indizes mit find(....<6)und rufen die entsprechenden Kommentare mit ab x[...].

Dennis
quelle
0

Python 3.5, 68 Bytes

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

Keine Übereinstimmung für meine Python 2-Antwort , aber nur drei Bytes länger als der Port zu Python 3, und ich denke, es ist anders genug, um interessant zu sein.

I / O ist in Form von Tupeln. Testen Sie es auf repl.it .

Dennis
quelle