Mostrar as cinco principais pontuações de comentários em uma postagem do SE


30

Um script do Stack Exchange determina quais cinco comentários sobre perguntas ou respostas são vistos inicialmente na página principal dos sites através do número de votos positivos; os cinco comentários com o maior número de votos são exibidos. Sua tarefa é recriar esse comportamento.

Escreva um programa ou função completo, recebendo entradas através de STDIN, argumentos de linha de comando ou argumentos de função e imprima ou retorne as cinco principais pontuações de comentários. A entrada será uma matriz de números inteiros representando o número de votos positivos nos comentários de alguma postagem. Por exemplo, uma entrada de

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

significa que o primeiro comentário não tem votos, o segundo tem dois votos, o terceiro tem cinco, o quarto tem quatro, etc. A ordem das pontuações dos comentários deve permanecer a mesma no resultado.

Se a entrada contiver cinco ou menos pontuações de comentários, a saída deverá conter nada mais do que os dados. Se duas ou mais pontuações de comentários forem iguais, as primeiras pontuações devem ser exibidas. Você pode assumir que a matriz de entrada conterá pelo menos uma pontuação de comentário.

Os números na saída devem ser facilmente distinguidos (portanto, 02541 para o caso 1 é inválido). Caso contrário, não há restrições no formato de saída; os números podem ser separados por um espaço ou nova linha, ou podem estar no formato de lista etc.

Casos de teste:

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

O último exemplo foi retirado dessa pergunta de estouro de pilha .

Se possível, forneça um link em sua postagem para que seu envio possa ser executado on-line.

Este é o código golf, portanto o código mais curto em bytes vence. Boa sorte!


Devemos manter a ordem?
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Sim. A ordem na qual os números inteiros aparecem não deve mudar.
TNT

Respostas:


10

Gelatina , 6 bytes

NỤḣ5Ṣị

Experimente online! ou verifique todos os casos de teste de uma só vez .

Como 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.

10

Python 2, 58 bytes

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

Teste em Ideone .

Como funciona

list.removeremove a primeira ocorrência se seu argumento da lista especificada. Ao reverter a lista x , basicamente conseguimos que ela remova a última ocorrência.

Portanto, basta remover o comentário com a quantidade mínima de votos até que uma lista de não mais que cinco comentários seja alcançada. Depois, revertemos a lista mais uma vez para restaurar o pedido original.


9

Pitão, 11 bytes

_.-_Q<SQ_5

Calculamos a interseção multiset da entrada ( Q) com os cinco maiores elementos em Q(na ordem em que aparecem Q) e, em seguida, obtemos os cinco primeiros.

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

Experimente aqui .


<5SQé equivalente a <SQ_5, o que economiza 1 byte.
PurkkaKoodari 27/01


Interessante. Eu me pergunto por que não foi implementado como b[:-a]... acho que pode ter sido isso em algum momento.
precisa saber é o seguinte

5

MATL , 16 bytes

tn4>?t_FT#S5:)S)

Isso usa a versão atual (10.2.1) , que é anterior a esse desafio.

Experimente online!

Explicação

          % 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 bytes

3 bytes de desconto, graças a @ user81655. 1 byte de desconto, graças a @apsillers.

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


5

Python 3, 76

Economizei 9 bytes graças a Kevin, lembrando-me que eu posso abusar das declarações if em uma lista comp.

Economizou 5 bytes graças ao DSM.

Solução bastante simples no momento. Pegue as 5 melhores pontuações e analise a lista adicionando-as ao resultado conforme as encontramos.

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

Aqui estão meus casos de teste, se alguém quiser:

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 bytes

Código:

E[Dg6‹#Rß\R

Explicação:

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

Usa a codificação CP-1252.


4

CJam, 16 bytes

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

Um bloco sem nome (função) que pega uma matriz e retorna uma matriz.

Suíte de teste.

Explicação

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 bytes

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

Exemplo de execução.

Um pedaço de embutidos. Eu acho que a melhor maneira de explicar é seguir um exemplo.

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

enumeratetransforma a lista em pares de índice / valor (tecnicamente um 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)]

Os pares são classificados pelo maior valor primeiro, mantendo a ordem atual do índice para empates. Isso coloca na frente os comentários mais pontuados, quebrados por post anterior. Então, os 5 melhores comentários são feitos.

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

Coloque os cinco principais comentários de volta na ordem de postagem e remova os índices, mantendo apenas as pontuações.


3

PowerShell v4, 120 97 bytes

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

Experimentando, encontrei uma abordagem alternativa que gerava alguns bytes adicionais. No entanto, parece ser específico para o PowerShell v4 e como essa versão lida com a classificação de uma hashtable - parece, por padrão, que na v4, se vários valores tiverem o mesmo valor, leva aquele com uma chave "inferior", mas você não está garantido na v3 ou anterior, mesmo ao usar a palavra-chave ordenada na v3. Ainda não testei isso totalmente no PowerShell v5 para dizer se o comportamento continua.

Esta versão somente da v4 recebe entrada como $ae cria uma nova hashtable vazia $b. Percorremos todos os elementos da entrada $a|%{...}e cada iteração adiciona um par de chave / valor a $b(feito pré-incrementando uma variável auxiliar $dcomo a chave para cada iteração). Em seguida, sort $bbaseamos em Value, então selecto -last 5, depois sortem Name(ou seja, a chave) e, finalmente, produzimos apenas os .Values do hash resultante.

Se menos de 5 elementos forem inseridos, ele apenas classificará o valor, selecionará os cinco últimos (ou seja, todos), reordenará a chave e a saída.


Mais antigo, 120 bytes, funciona em versões anteriores

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

O mesmo algoritmo da resposta de Morgan Thrapp , que aparentemente é uma indicação de que grandes mentes pensam da mesma forma. :)

Recebe entrada, verifica se o número de itens é menor ou igual a 5 e, se assim for, gera a entrada e sai. Caso contrário, criamos um ArrayList $b(com o [System.Collections.ArrayList]elenco exorbitantemente longo ) dos cinco principais elementos de $a. Em seguida, iteramos sobre $ae para cada elemento, se estiver na $bsaída e o removemos $b(e aqui está o motivo pelo qual precisamos usar o ArrayList, pois remover elementos de um Array não é um recurso suportado no PowerShell, pois eles são tecnicamente corrigidos Tamanho).

Requer v3 ou superior para o -inoperador. Para uma resposta que funciona nas versões anteriores, troca $_-in$bpara $b-contains$_um total de 126 bytes .


2

Haskell, 62 bytes

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

Exemplo 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].

Como funciona: aumente cada elemento com seu índice, classifique decrescente, pegue os 5 primeiros elementos, classifique por índice e remova o índice.


2

PHP 5, 107 102

Guardado 5 bytes graças 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;
}

Tente.


Pois 1 1 5 1 1 5, sua submissão produz uma saída em 1 5 1 1 5vez da correta 1 1 5 1 5.
TNT

Parece se comportar de maneira diferente no PHP 7.X, altere a versão do PHP para 5.6 ou abaixo.
Samsquanch

Entendi, não percebeu o número da versão. :)
TNT

Eu também não. Não sei por que isso não salva a versão usada e o código. Também não sei por que ele não funciona corretamente no 7.X.
Samsquanch

@WashingtonGuedes A remoção de espaços me salvou 5 bytes, mas não estou vendo ponto e vírgula desnecessário que não geraria um erro?
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)

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

envio original - 56 bytes, mas falha em determinados casos de teste e não suportava $ stdin e $ stdout

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

Explicação

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

Bom programa. Você pode ter que perguntar ao OP sobre isso. Não tenho certeza se o formato de entrada está correto.
Rɪᴋᴇʀ

@RikerW ele realmente falhar quando há uma duplicata top # na última indice, estou modificando-o agora
John

O @RikerW está corrigido agora e suporta stdin e grava no stdout.
John

OK. Eu gosto do método de entrada embora. Eu estava dizendo para perguntar à @TNT sobre isso.
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;}

Ungolfed & test-code:

Experimente aqui.

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

Saída:

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

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

Experimente online!

Como funciona

O comentário c 1 tem precedência mais alta que o comentário c 2 se um dos seguintes for verdadeiro:

  • c 1 tem mais votos positivos que c 2 .
  • c 1 e c 2 têm a mesma quantidade de votos positivos, mas c 1 foi postado anteriormente.

Isso define uma ordem total dos comentários, e a tarefa em questão é encontrar os cinco comentários que têm as precedências mais altas.

Em vez de classificar os comentários por precedência (o que alteraria sua ordem, para cada comentário c , contamos os comentários que têm uma precedência maior ou igual. Mantemos c se e somente se essa contagem for 5 ou menos.

Para classificar parcialmente os comentários por número de votos positivos, fazemos o seguinte. Seja x o vetor da coluna que contém a contagem de votos. Em seguida, x'transpõe x - criando, assim, um vector da linha - e x.<x'cria uma matriz booleano que compara cada um dos elementos de x , com cada elemento de x t .

Para x = [0, 2, 5, 4, 0, 1, 0] , isso fornece

<     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

Ao somar linhas (via sum(...,2)), contamos o número de comentários que têm estritamente mais votos que o comentário nesse índice.

Para o vetor de exemplo, isso fornece

4
2
0
1
4
3
4

Em seguida, contamos o número de comentários com uma quantidade igual de upvotes publicados antes desse comentário. Conseguimos isso da seguinte maneira.

Em primeiro lugar, construir uma tabela a igualdade com x.==x'que compraes os elementos de x com os elementos de x T . Para o nosso vetor de exemplo, isso fornece:

=     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

Em seguida, usamos cumsumpara calcular as somas cumulativas de cada coluna da 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

A diagonal ( diag) contém a contagem de comentários que têm uma quantidade igual de votos positivos e ocorrem o mais tardar no comentário correspondente.

1
1
1
1
2
1
3

Ao adicionar os dois vetores de linha que produzimos, obtemos as prioridades ( 1 é a mais alta) dos comentários.

5
3
1
2
6
4
7

Os comentários com prioridades que variam de 1 a 5 devem ser exibidos, para que determinemos seus índices find(....<6)e recuperemos os comentários correspondentes x[...].


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)

Não é páreo para a minha resposta do Python 2 , mas apenas três bytes a mais do que sua porta para o Python 3, e acho que é diferente o suficiente para ser interessante.

A E / S está na forma de tuplas. Testá-lo em repl.it .

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.