Mostra i primi cinque punteggi dei commenti su un post SE


30

Uno script Stack Stack determina quali cinque commenti su domande o risposte vengono inizialmente visualizzati sulla pagina principale dei siti attraverso il numero di voti su di essi; vengono visualizzati i cinque commenti con il maggior numero di voti. Il tuo compito è ricreare questo comportamento.

Scrivi un programma o una funzione completi prendendo input tramite STDIN, argomenti della riga di comando o argomenti di funzioni e stampa o restituisce i primi cinque punteggi dei commenti. L'input sarà un array di numeri interi che rappresentano il numero di voti sui commenti di alcuni post. Ad esempio, un input di

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

significa che il primo commento non ha voti, il secondo ha due voti, il terzo ha cinque, il quarto ha quattro, ecc. L'ordine dei punteggi dei commenti dovrebbe rimanere lo stesso nell'output.

Se l'input contiene cinque o meno punteggi di commento, l'output non dovrebbe contenere altro che quelli indicati. Se due o più punteggi di commento sono uguali, devono essere visualizzati i primi punteggi. Si può presumere che l'array di input conterrà almeno un punteggio di commento.

I numeri nell'output dovrebbero essere facilmente distinti (quindi 02541 per il caso 1 non è valido). Altrimenti non ci sono restrizioni sul formato di output; i numeri possono essere separati da uno spazio o da una nuova riga oppure possono essere in formato elenco, ecc.

Casi test:

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

L'ultimo esempio è stato preso da questa domanda Stack Overflow .

Se possibile, si prega di fornire un collegamento nel proprio post in cui è possibile eseguire l'invio online.

Questo è il codice golf, quindi vince il codice più breve in byte. In bocca al lupo!


Dobbiamo conservare l'ordine?
Conor O'Brien,

@ CᴏɴᴏʀO'Bʀɪᴇɴ Sì. L'ordine in cui compaiono gli interi non dovrebbe cambiare.
TNT,

Risposte:


10

Gelatina , 6 byte

NỤḣ5Ṣị

Provalo online! oppure verifica tutti i casi di test contemporaneamente .

Come funziona

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.

10

Python 2, 58 byte

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

Provalo su Ideone .

Come funziona

list.removerimuove la prima occorrenza se il suo argomento dall'elenco specificato. Invertendo l'elenco x , in sostanza si ottiene che rimuove invece l' ultima occorrenza.

Pertanto, è sufficiente continuare a rimuovere il commento con la quantità minima di voti fino a quando non viene raggiunto un elenco di non più di cinque commenti. Successivamente, invertire nuovamente l'elenco per ripristinare l'ordine originale.


9

Pyth, 11 byte

_.-_Q<SQ_5

Calcoliamo l'intersezione multiset dell'input ( Q) con i cinque elementi maggiori in Q(nell'ordine in cui compaionoQ ), quindi prendiamo i primi cinque di quelli.

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

Provalo qui .


<5SQè equivalente a <SQ_5, che consente di risparmiare 1 byte.
PurkkaKoodari,


Interessante. Mi chiedo perché non sia implementato come b[:-a]... Penso che potrebbe anche essere stato ad un certo punto.
PurkkaKoodari,

5

MATL , 16 byte

tn4>?t_FT#S5:)S)

Questo utilizza la versione corrente (10.2.1) , che è precedente a questa sfida.

Provalo online!

Spiegazione

          % 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

5

JavaScript, 74 65 62 61 byte

3 byte di sconto grazie @ user81655. 1 byte spento grazie a @apsillers.

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


5

Python 3, 76

Salvataggio di 9 byte grazie a Kevin che mi ricorda che posso abusare delle dichiarazioni in un elenco comp.

5 byte salvati grazie a DSM.

Soluzione abbastanza semplice in questo momento. Prendi i primi 5 punteggi e poi analizza l'elenco aggiungendoli al risultato appena li troviamo.

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

Ecco i miei casi di test se qualcuno li desidera:

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]

4

05AB1E , 12 11 byte

Codice:

E[Dg6‹#Rß\R

Spiegazione:

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

Utilizza la codifica CP-1252.


4

CJam, 16 byte

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

Un blocco senza nome (funzione) che accetta un array e restituisce un array.

Suite di test.

Spiegazione

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.


3

Python, 68 byte

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

Esempio di esecuzione.

Un grumo di built-in. Penso che il modo migliore per spiegare sia fare un esempio.

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

enumeratetrasforma l'elenco in coppie indice / valore (tecnicamente un enumerateoggetto).

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

Le coppie vengono ordinate per prime per valore più elevato, mantenendo l'ordine corrente dell'indice per i legami. Questo mette in primo piano i commenti più votati, interrotti da post precedenti. Quindi, vengono presi i 5 migliori commenti di questo tipo.

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

Riporta i primi cinque commenti in ordine di pubblicazione, quindi rimuovi gli indici, mantenendo solo i punteggi.


3

PowerShell v4, 120 97 byte

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

Sperimentando in giro, ho trovato un approccio alternativo che sfruttava alcuni byte aggiuntivi. Tuttavia, sembra essere specifico per PowerShell v4 e come quella versione gestisce l'ordinamento di una tabella hash - sembra, per impostazione predefinita, che in v4 se più valori hanno lo stesso valore, prende quello con una chiave "inferiore", ma non è garantito che in v3 o precedenti, anche quando si utilizza l' ordine parola chiave in v3. Non l'ho verificato completamente su PowerShell v5 per dire se il comportamento continua.

Questa versione solo v4 accetta input as $a, quindi crea una nuova tabella hash vuota $b. Esaminiamo tutti gli elementi dell'input $a|%{...}e ogni iterazione aggiunge una coppia chiave / valore a $b(eseguita pre-incrementando una variabile helper $dcome chiave per ogni iterazione). Poi si sort $briferiscono al Value, allora l'AST , poi da (cioè, la chiave), ed infine in uscita solo le s del hash risultante.select-l5sortName.Value

Se vengono inseriti meno di 5 elementi, ordinerà semplicemente il valore, selezionerà gli ultimi cinque (cioè tutti), riordinerà il tasto e l'output.


Vecchio, 120 byte, funziona nelle versioni precedenti

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

Stesso algoritmo della risposta di Morgan Thrapp , che apparentemente indica che grandi menti pensano allo stesso modo. :)

Accetta input, controlla se il numero di elementi è inferiore o uguale a 5 e, in tal caso, genera input ed esce. Altrimenti, creiamo una ArrayList $b(con il [System.Collections.ArrayList]cast esorbitantemente lungo ) dei primi cinque elementi di $a. Quindi eseguiamo iterazioni su $ae per ogni elemento se è presente, lo $beseguiamo in output e quindi lo rimuoviamo da $b(ed ecco perché dobbiamo usare ArrayList, poiché la rimozione di elementi da un array non è una funzionalità supportata in PowerShell, poiché sono tecnicamente risolti dimensione).

Richiede v3 o superiore per l' -inoperatore. Per una risposta che funziona nelle versioni precedenti, di swap $_-in$bper $b-contains$_per un totale di 126 byte .


2

Haskell, 62 byte

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

Esempio di utilizzo: 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].

Come funziona: aumenta ogni elemento con il suo indice, ordina in ordine decrescente, prendi i primi 5 elementi, ordina per indice e rimuovi indice.


2

PHP 5, 107 102

5 byte salvati grazie a @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;
}

Provalo.


Per 1 1 5 1 1 5, il tuo invio produce un output 1 5 1 1 5anziché il corretto 1 1 5 1 5.
TNT,

Sembra comportarsi diversamente per PHP 7.X, cambiare la versione di PHP in 5.6 o precedente.
Samsquanch,

Gotcha, non ho notato il numero di versione. :)
TNT,

Nemmeno io all'inizio. Non sono sicuro del perché ciò non salvi la versione utilizzata e il codice. Inoltre non sono sicuro del perché non funzioni correttamente su 7.X.
Samsquanch,

@WashingtonGuedes La rimozione di spazi mi ha salvato 5 byte, ma non vedo alcun punto e virgola non necessario che non genererebbe un errore?
Samsquanch,

0

Rubino, 82 87 89 byte

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

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

invio originale - 56 byte, ma fallisce in alcuni casi di test e non supporta $ stdin e $ stdout

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

Spiegazione

$><<               # 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

Bel programma. Tuttavia, potresti dover chiedere al PO. Non sono sicuro che il formato di input sia corretto.
Rɪᴋᴇʀ

@RikerW in realtà fallisce quando c'è un top # duplicato nell'ultimo indice, lo sto modificando ora
John

@RikerW è stato risolto ora e supporta stdin e scrive su stdout.
Giovanni

Va bene. Mi piace il metodo di input però. Stavo solo dicendo di chiedere a @TNT a riguardo.
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;}

Ungolfed e codice di prova:

Provalo qui.

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

Produzione:

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

0

Julia, 48 byte

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

Provalo online!

Come funziona

Il commento c 1 ha una precedenza maggiore rispetto al commento c 2 se una delle seguenti affermazioni è vera:

  • c 1 ha più voti di c 2 .
  • c 1 e c 2 hanno la stessa quantità di voti positivi, ma c 1 è stato pubblicato in precedenza.

Ciò definisce un ordinamento totale dei commenti e l'attività a portata di mano è quella di trovare i cinque commenti che hanno le precedenza più alte.

Invece di ordinare i commenti per precedenza (che altererebbe il loro ordine, per ogni commento c , contiamo i commenti che hanno una precedenza maggiore o uguale. c se e solo se questo conteggio è 5 o meno.

Per ordinare parzialmente i commenti per numero di voti, facciamo quanto segue. Sia x il vettore della colonna che contiene i conteggi dei voti. Quindi x'traspone x - creando così un vettore di riga - e x.<x'crea una matrice booleana che confronta ogni elemento di x con ciascun elemento di x T .

Per x = [0, 2, 5, 4, 0, 1, 0] , questo dà

<     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

Sommando le righe (via sum(...,2)), contiamo il numero di commenti che hanno rigorosamente più voti rispetto al commento in quell'indice.

Per il vettore di esempio, questo dà

4
2
0
1
4
3
4

Quindi, contiamo il numero di commenti con un uguale numero di voti sono stati pubblicati prima di quel commento. Raggiungiamo questo come segue.

Per prima cosa costruiamo una tabella di uguaglianza con x.==x', che compra gli elementi di x con gli elementi di x T . Per il nostro esempio vettoriale, questo dà:

=     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

Successivamente, usiamo cumsumper calcolare le somme cumulative di ciascuna colonna della matrice.

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

La diagonale ( diag) contiene il conteggio dei commenti che hanno un uguale numero di voti positivi e si verificano non oltre il commento corrispondente.

1
1
1
1
2
1
3

Aggiungendo i due vettori di riga che abbiamo prodotto, otteniamo le priorità ( 1 è il più alto) dei commenti.

5
3
1
2
6
4
7

Dovrebbero essere visualizzati i commenti con priorità che vanno da 1 a 5 , quindi determiniamo i loro indici con find(....<6)e recuperiamo i commenti corrispondenti con x[...].


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)

Nessuna corrispondenza per la mia risposta Python 2 , ma solo tre byte in più rispetto alla sua porta a Python 3, e penso che sia abbastanza diverso da essere interessante.

L'I / O è in forma di tuple. Testarlo su repl.it .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.