Mostrar las mejores puntuaciones de cinco comentarios en una publicación SE

30

Un script de Stack Exchange determina qué cinco comentarios sobre preguntas o respuestas se ven inicialmente en la página principal de los sitios a través de la cantidad de votos positivos en ellos; Se muestran los cinco comentarios con el mayor número de votos. Su tarea es recrear este comportamiento.

Escriba un programa completo o una función tomando datos a través de STDIN, argumentos de línea de comandos o argumentos de funciones e imprime o devuelve los cinco puntajes de comentarios principales. La entrada será un conjunto de enteros que representa el número de votos a favor en los comentarios de alguna publicación. Por ejemplo, una entrada de

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

significa que el primer comentario no tiene votos, el segundo tiene dos votos, el tercero tiene cinco, el cuarto tiene cuatro, etc. El orden de las puntuaciones de los comentarios debe permanecer igual en la salida.

Si la entrada contiene cinco o menos puntajes de comentarios, entonces la salida no debe contener más que los dados. Si dos o más puntajes de comentarios son iguales, se deben mostrar los primeros puntajes. Puede suponer que la matriz de entrada contendrá al menos una puntuación de comentario.

Los números en la salida deben distinguirse fácilmente (por lo que 02541 para el caso 1 no es válido). De lo contrario, no hay restricciones en el formato de salida; los números pueden estar separados por un espacio o una nueva línea, o pueden estar en formato de lista, etc.

Casos de prueba:

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

El último ejemplo fue tomado de esta pregunta de desbordamiento de pila .

Si es posible, proporcione un enlace en su publicación donde su envío se pueda ejecutar en línea.

Este es el código de golf, por lo que gana el código más corto en bytes. ¡Buena suerte!

TNT
fuente
¿Debemos retener el orden?
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ Sí. El orden en que aparecen los enteros no debe cambiar.
TNT

Respuestas:

10

Jalea , 6 bytes

NỤḣ5Ṣị

Pruébalo en línea! o verificar todos los casos de prueba a la vez .

Cómo funciona

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

Python 2, 58 bytes

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

Pruébalo en Ideone .

Cómo funciona

list.removeelimina la primera aparición si su argumento de la lista especificada. Al invertir la lista x , esencialmente logramos que elimine la última ocurrencia en su lugar.

Por lo tanto, es suficiente seguir eliminando el comentario con la mínima cantidad de votos positivos hasta que se llegue a una lista de no más de cinco comentarios. Luego, revertimos la lista una vez más para restaurar el orden original.

Dennis
fuente
9

Pyth, 11 bytes

_.-_Q<SQ_5

Calculamos la intersección de múltiples conjuntos de la entrada ( Q) con los cinco elementos más grandes en Q(en el orden en que aparecen Q), luego tomamos los primeros cinco de esos.

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

Probarlo aquí .

lirtosiast
fuente
<5SQes equivalente a <SQ_5, que ahorra 1 byte.
PurkkaKoodari
Nop .
lirtosiast
Interesante. Me pregunto por qué no se implementa como b[:-a]... Creo que incluso podría haber sido así en algún momento.
PurkkaKoodari
5

MATL , 16 bytes

tn4>?t_FT#S5:)S)

Utiliza la versión actual (10.2.1) , que es anterior a este desafío.

Pruébalo en línea!

Explicación

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

JavaScript, 74 65 62 61 bytes

3 bytes de descuento gracias @ user81655. 1 byte off gracias @apsillers.

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

remoto
fuente
5

Pitón 3, 76

Ahorré 9 bytes gracias a Kevin recordándome que puedo abusar si las declaraciones en una lista de comp.

Guardado 5 bytes gracias a DSM.

Solución bastante simple en este momento. Tome los 5 mejores puntajes y luego analice la lista agregándolos al resultado a medida que los encontremos.

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

Aquí están mis casos de prueba si alguien los quiere:

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

05AB1E , 12 11 bytes

Código:

E[Dg6‹#Rß\R

Explicación:

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

Utiliza la codificación CP-1252.

Adnan
fuente
4

CJam, 16 bytes

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

Un bloque (función) sin nombre que toma una matriz y devuelve una matriz.

Banco de pruebas.

Explicación

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

Bash + utilidades GNU, 36

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

E / S formateadas como listas separadas por nueva línea a través de STDIN / STDOUT.

Pruébalo en línea.

Trauma digital
fuente
3

Python, 68 bytes

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

Ejemplo de ejecución.

Un bulto de empotrados. Creo que la mejor manera de explicar es analizar un ejemplo.

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

enumerateconvierte la lista en pares índice / valor (técnicamente un enumerateobjeto).

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

Los pares se ordenan primero por el mayor valor, manteniendo el orden actual del índice para los lazos. Esto pone al frente los comentarios mejor calificados, quebrados por una publicación anterior. Luego, se toman los 5 mejores comentarios.

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

Vuelva a colocar los cinco comentarios principales en orden de publicación y luego elimine los índices, manteniendo solo los puntajes.

xnor
fuente
3

PowerShell v4, 120 97 bytes

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

Experimentando, encontré un enfoque alternativo que arrojó algunos bytes adicionales. Sin embargo, parece ser específico para PowerShell v4 y cómo esa versión maneja la clasificación de una tabla hash: parece que, por defecto, en v4 si varios valores tienen el mismo valor, toma el que tiene una clave "inferior", pero no está garantizado eso en v3 o anterior, incluso cuando se usa la palabra clave ordenada en v3. No he investigado completamente esto contra PowerShell v5 para decir si el comportamiento continúa.

Esta versión solo para v4 toma la entrada como $a, luego crea una nueva tabla hash vacía $b. Recorremos todos los elementos de la entrada $a|%{...}y cada iteración agrega un par clave / valor a $b(hecho mediante el incremento previo de una variable auxiliar $dcomo la clave para cada iteración). Luego nos sort $bbasamos en Value, luego en selectel -last 5, luego sorten Name(es decir, la clave), y finalmente sacamos solo los .Values del hash resultante.

Si se ingresan menos de 5 elementos, solo ordenará el valor, seleccionará los últimos cinco (es decir, todos), volverá a ordenar la clave y generará la salida.


Más viejo, 120 bytes, funciona en versiones anteriores

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

El mismo algoritmo que la respuesta de Morgan Thrapp , que aparentemente es una indicación de que las grandes mentes piensan igual. :)

Toma entrada, verifica si el número de elementos es menor o igual a 5, y si es así, genera la entrada y sale. De lo contrario, creamos una ArrayList $b(con el [System.Collections.ArrayList]reparto exorbitantemente largo ) de los cinco elementos principales de $a. Luego iteramos sobre $ay para cada elemento si está dentro, lo $bsacamos y luego $blo eliminamos (y esta es la razón por la que necesitamos usar ArrayList, ya que eliminar elementos de un Array no es una característica compatible en PowerShell, ya que son técnicamente fijos tamaño).

Requiere v3 o superior para el -inoperador. Para una respuesta que funciona en las versiones anteriores, de intercambio $_-in$bpara $b-contains$_un total de 126 bytes .

AdmBorkBork
fuente
2

Haskell, 62 bytes

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

Ejemplo de uso: 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].

Cómo funciona: aumente cada elemento con su índice, ordene descendente, tome los primeros 5 elementos, ordene por índice y elimine el índice.

nimi
fuente
2

PHP 5, 107 102

Guardado 5 bytes gracias a @WashingtonGuedes

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

Sin golf

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

Intentalo.

Samsquanch
fuente
Para 1 1 5 1 1 5, su presentación produce una salida de en 1 5 1 1 5lugar de la correcta 1 1 5 1 5.
TNT
Parece que se comporta de manera diferente para PHP 7.X, cambie la versión de PHP a 5.6 o inferior.
Samsquanch
Gotcha, no noté el número de versión. :)
TNT
Yo tampoco al principio. No estoy seguro de por qué eso no guarda la versión utilizada, así como el código. Tampoco estoy seguro de por qué no funciona correctamente en 7.X.
Samsquanch
@WashingtonGuedes Eliminar espacios me ahorró 5 bytes, pero no veo ningún punto y coma innecesario que no arroje un error.
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)

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

envío original - 56 bytes pero falla en ciertos casos de prueba y no admite $ stdin y $ stdout

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

Explicación

$><<               # 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
fuente
Buen programa Sin embargo, es posible que deba preguntarle al OP. No estoy seguro de que el formato de entrada esté bien.
Rɪᴋᴇʀ
@RikerW en realidad falla cuando hay un top # duplicado en el último índice, lo estoy modificando ahora
John
@RikerW está arreglado ahora, y admite stdin y escribe en stdout.
John
Bueno. Aunque me gusta el método de entrada. Solo decía que le preguntara a @TNT al respecto.
Rɪᴋᴇʀ
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;}

Sin código y código de prueba:

Pruébalo aquí.

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

Salida:

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

Julia, 48 bytes

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

Pruébalo en línea!

Cómo funciona

El comentario c 1 tiene mayor prioridad que el comentario c 2 si uno de los siguientes es verdadero:

  • c 1 tiene más votos a favor que c 2 .
  • c 1 y c 2 tienen la misma cantidad de votos a favor, pero c 1 se publicó anteriormente.

Esto define un orden total de los comentarios, y la tarea en cuestión es encontrar los cinco comentarios que tienen las mayores precedencia.

En lugar de ordenar los comentarios por precedencia (lo que alteraría su orden, para cada comentario c , contamos los comentarios que tienen una precedencia mayor o igual. Mantenemos c si y solo si este recuento es 5 o menos.

Para ordenar parcialmente los comentarios por número de votos a favor, hacemos lo siguiente. Sea x el vector de columna que contiene los recuentos de votos. Entonces x'transpuestas x - creando así un vector fila - y x.<x'crea una matriz booleana que compara cada elemento de x con cada elemento de x T .

Para x = [0, 2, 5, 4, 0, 1, 0] , esto da

<     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

Al sumar entre filas (vía sum(...,2)), contamos el número de comentarios que tienen estrictamente más votos positivos que el comentario en ese índice.

Para el vector de ejemplo, esto da

4
2
0
1
4
3
4

A continuación, contamos el número de comentarios con una cantidad igual de votos positivos que se han publicado antes de ese comentario. Logramos esto de la siguiente manera.

En primer lugar construimos una tabla de igualdad con los x.==x'que compraes los elementos de x con los elementos de x T . Para nuestro vector de ejemplo, esto da:

=     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

A continuación, usamos cumsumpara calcular las sumas acumulativas de cada columna de la matriz.

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 diagonal ( diag) contiene el recuento de comentarios que tienen la misma cantidad de votos a favor y ocurren a más tardar en el comentario correspondiente.

1
1
1
1
2
1
3

Al agregar los dos vectores de fila que produjimos, obtenemos las prioridades ( 1 es la más alta) de los comentarios.

5
3
1
2
6
4
7

Deben mostrarse los comentarios con prioridades que van del 1 al 5 , por lo que determinamos sus índices con find(....<6)y recuperamos los comentarios correspondientes con x[...].

Dennis
fuente
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)

No hay coincidencia para mi respuesta de Python 2 , pero solo tres bytes más largos que su puerto para Python 3, y creo que es lo suficientemente diferente como para ser interesante.

I / O está en forma de tuplas. Probarlo en repl.it .

Dennis
fuente