Afficher les cinq meilleurs scores de commentaires sur un message SE


30

Un script Stack Exchange détermine quels cinq commentaires sur les questions ou réponses sont initialement vus sur la page principale des sites à travers le nombre de votes positifs sur eux; les cinq commentaires avec le plus grand nombre de votes sont affichés. Votre tâche consiste à recréer ce comportement.

Écrivez un programme ou une fonction complet prenant des entrées via STDIN, des arguments de ligne de commande ou des arguments de fonction et imprime ou renvoie les cinq premiers scores de commentaire. L'entrée sera un tableau d'entiers représentant le nombre de votes positifs sur les commentaires de certains messages. Par exemple, une entrée de

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

signifie que le premier commentaire n'a pas de votes, le second a deux votes, le troisième a cinq, le quatrième en a quatre, etc. L'ordre des scores des commentaires doit rester le même dans la sortie.

Si l'entrée contient cinq scores de commentaire ou moins, la sortie ne doit contenir rien de plus que ceux donnés. Si deux ou plusieurs scores de commentaires sont identiques, le ou les premiers scores doivent être affichés. Vous pouvez supposer que le tableau d'entrée contiendra au moins un score de commentaire.

Les nombres dans la sortie doivent être facilement distingués (donc 02541 pour le cas 1 n'est pas valide). Sinon, il n'y a aucune restriction sur le format de sortie; les numéros peuvent être séparés par un espace ou une nouvelle ligne, ou ils peuvent être sous forme de liste, etc.

Cas de 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]

Le dernier exemple a été tiré de cette question Stack Overflow .

Si possible, veuillez fournir un lien dans votre message où votre soumission peut être exécutée en ligne.

Il s'agit du code golf, donc le code le plus court en octets l'emporte. Bonne chance!


Faut-il conserver l'ordre?
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Oui. L'ordre dans lequel les entiers apparaissent ne doit pas changer.
TNT

Réponses:


10

Gelée , 6 octets

NỤḣ5Ṣị

Essayez-le en ligne! ou vérifiez tous les cas de test à la fois .

Comment ça marche

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 octets

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

Testez-le sur Ideone .

Comment ça marche

list.removesupprime la première occurrence si son argument de la liste spécifiée. En inversant la liste x , nous obtenons essentiellement qu'il supprime la dernière occurrence à la place.

Ainsi, il suffit de continuer à supprimer le commentaire avec le minimum de votes positifs jusqu'à ce qu'une liste de cinq commentaires au maximum soit atteinte. Ensuite, nous inversons une fois de plus la liste pour rétablir l'ordre d'origine.


9

Pyth, 11 octets

_.-_Q<SQ_5

Nous calculons l'intersection multiset de l'entrée ( Q) avec les cinq plus grands éléments dans Q(dans l'ordre dans lequel ils apparaissent Q), puis prenons les cinq premiers de ceux-ci.

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

Essayez-le ici .


<5SQest équivalent à <SQ_5, ce qui économise 1 octet.
PurkkaKoodari


Intéressant. Je me demande pourquoi ce n'est pas implémenté car b[:-a]...
PurkkaKoodari

5

MATL , 16 octets

tn4>?t_FT#S5:)S)

Cela utilise la version actuelle (10.2.1) , qui est antérieure à ce défi.

Essayez-le en ligne!

Explication

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

3 octets de réduction merci @ user81655. 1 octet de moins merci @apsillers.

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


5

Python 3, 76

Enregistré 9 octets grâce à Kevin me rappelant que je peux abuser des instructions if dans une liste comp.

5 octets enregistrés grâce à DSM.

Solution assez simple en ce moment. Saisissez les 5 meilleurs scores, puis parcourez la liste en les ajoutant au résultat au fur et à mesure que nous les trouvons.

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

Voici mes cas de test si quelqu'un en veut:

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 octets

Code:

E[Dg6‹#Rß\R

Explication:

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

Utilise l'encodage CP-1252.


4

CJam, 16 octets

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

Un bloc sans nom (fonction) qui prend un tableau et renvoie un tableau.

Suite de tests.

Explication

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 octets

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

Exemple d'exécution.

Un ensemble de modules intégrés. Je pense que la meilleure façon d'expliquer est de parcourir un exemple.

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

enumeratetransforme la liste en paires index / valeur (techniquement un enumerateobjet).

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

Les paires sont d'abord triées selon leur valeur la plus élevée, en conservant l'ordre d'index actuel des liens. Cela place au premier plan les commentaires les mieux notés, rompus par un message précédent. Ensuite, les 5 meilleurs commentaires sont pris.

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

Remettez les cinq premiers commentaires dans l'ordre de publication, puis supprimez les indices, en ne conservant que les scores.


3

PowerShell v4, 120 97 octets

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

Expérimentant autour, j'ai trouvé une approche alternative qui a joué au golf quelques octets supplémentaires. Cependant, il semble être spécifique à PowerShell v4 et à la façon dont cette version gère le tri d'une table de hachage - il semble, par défaut, qu'en v4 si plusieurs valeurs ont la même valeur, il prend celle avec une clé "inférieure", mais vous n'êtes pas assuré que dans la version 3 ou antérieure, même lorsque vous utilisez le mot clé ordonné dans la version 3. Je n'ai pas entièrement vérifié cela contre PowerShell v5 pour dire si le comportement persiste.

Cette version v4 uniquement prend l'entrée en tant que $a, puis crée une nouvelle table de hachage vide $b. Nous parcourons tous les éléments de l'entrée $a|%{...}et chaque itération ajoute une paire clé / valeur à $b(effectuée en pré-incrémentant une variable d'assistance $dcomme clé pour chaque itération). Ensuite , nous avons sort $bbasé sur Value, puis selectle -last 5, puis sortpar Name(c. -à- la clé), et enfin la sortie que les .Values du hachage résultant.

Si moins de 5 éléments sont entrés, il suffit de trier sur la valeur, de sélectionner les cinq derniers (c'est-à-dire tous), de trier à nouveau sur la clé et de sortir.


Plus ancien, 120 octets, fonctionne dans les versions antérieures

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

Même algorithme que la réponse de Morgan Thrapp , ce qui est apparemment une indication que les grands esprits pensent de la même façon. :)

Prend l'entrée, vérifie si le nombre d'éléments est inférieur ou égal à 5, et si c'est le cas, génère l'entrée et quitte. Sinon, nous créons une ArrayList $b(avec la [System.Collections.ArrayList]distribution exorbitante et longue ) des cinq premiers éléments de $a. Nous répétons ensuite$a et pour chaque élément s'il se trouve, $bnous le sortons et le supprimons de $b(et voici pourquoi nous devons utiliser ArrayList, car la suppression d'éléments d'un tableau n'est pas une fonctionnalité prise en charge dans PowerShell, car ils sont techniquement fixes Taille).

Nécessite la version 3 ou supérieure pour l' -inopérateur. Pour une réponse qui fonctionne dans les versions antérieures, échange $_-in$bpour $b-contains$_un total de 126 octets .


2

Haskell, 62 octets

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

Exemple d'utilisation: 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].

Comment ça marche: augmentez chaque élément avec son index, triez en ordre décroissant, prenez les 5 premiers éléments, triez par index et supprimez l'index.


2

PHP 5, 107 102

5 octets enregistrés grâce à @WashingtonGuedes

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

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

Essayez-le.


Pour 1 1 5 1 1 5, votre soumission produit une sortie 1 5 1 1 5au lieu de la bonne 1 1 5 1 5.
TNT

Il semble se comporter différemment pour PHP 7.X, passez la version PHP à 5.6 ou inférieure.
Samsquanch

Gotcha, n'a pas remarqué le numéro de version. :)
TNT

Moi non plus au début. Je ne sais pas pourquoi cela ne sauvegarde pas la version utilisée ainsi que le code. Je ne sais pas non plus pourquoi cela ne fonctionne pas correctement sur 7.X.
Samsquanch

@WashingtonGuedes La suppression d'espaces m'a fait économiser 5 octets, mais je ne vois aucun point-virgule inutile qui ne générerait pas d'erreur?
Samsquanch

0

Rubis, 82 87 89 octets

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

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

soumission d'origine - 56 octets mais échoue sur certains cas de test et n'a pas pris en charge $ stdin et $ stdout

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

Explication

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

Bon programme. Vous devrez peut-être demander au PO à ce sujet. Je ne suis pas sûr que le format d'entrée soit correct.
Rɪᴋᴇʀ

@RikerW il échoue en fait quand il y a un top # en double dans le dernier indice, je le modifie maintenant
John

@RikerW est maintenant corrigé et prend en charge stdin et écrit sur stdout.
John

D'accord. J'aime bien la méthode de saisie. Je disais juste de demander à @TNT à ce sujet.
Rɪᴋᴇʀ

0

Java 7, 155 octets

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

Code non testé et de test:

Essayez-le ici.

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

Sortie:

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

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

Essayez-le en ligne!

Comment ça marche

Le commentaire c 1 a une priorité plus élevée que le commentaire c 2 si l'une des conditions suivantes est vraie:

  • c 1 a plus de votes positifs que c 2 .
  • c 1 et c 2 ont le même nombre de votes positifs, mais c 1 a été publié plus tôt.

Cela définit un ordre total des commentaires, et la tâche à accomplir consiste à trouver les cinq commentaires qui ont les plus hautes priorités.

Au lieu de trier les commentaires par ordre de priorité (ce qui modifierait leur ordre, pour chaque commentaire c , nous comptons les commentaires qui ont une priorité supérieure ou égale. Nous gardons c si et seulement si ce nombre est 5 ou moins.

Pour trier partiellement les commentaires par nombre de votes positifs, nous procédons comme suit. Soit x le vecteur colonne contenant le nombre de votes. x'Transpose ensuite x - créant ainsi un vecteur ligne - et x.<x'crée une matrice booléenne qui compare chaque élément de x à chaque élément de x T .

Pour x = [0, 2, 5, 4, 0, 1, 0] , cela donne

<     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

En additionnant sur plusieurs lignes (via sum(...,2) ), nous comptons le nombre de commentaires qui ont strictement plus votes positifs que le commentaire de cet index.

Pour l'exemple de vecteur, cela donne

4
2
0
1
4
3
4

Ensuite, nous comptons le nombre de commentaires avec un nombre égal de votes positifs qui ont été publiés plus tôt que ce commentaire. Nous y parvenons comme suit.

D' abord , nous construisons une table d'égalité avec x.==x'qui compraes les éléments de x avec les éléments de x T . Pour notre vecteur d'exemple, cela donne:

=     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

Ensuite, nous utilisons cumsumpour calculer les sommes cumulées de chaque colonne de la 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) contient le nombre de commentaires qui ont un nombre égal de votes positifs et se produisent au plus tard le commentaire correspondant.

1
1
1
1
2
1
3

En ajoutant les deux vecteurs de lignes que nous avons produits, nous obtenons les priorités ( 1 est la plus élevée) des commentaires.

5
3
1
2
6
4
7

Les commentaires avec des priorités allant de 1 à 5 doivent être affichés, nous déterminons donc leurs indices avec find(....<6)et récupérons les commentaires correspondants avec x[...].


0

Python 3.5, 68 octets

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

Pas de correspondance pour ma réponse Python 2 , mais seulement trois octets de plus que son port vers Python 3, et je pense que c'est suffisamment différent pour être intéressant.

Les E / S sont sous forme de tuples. Testez - le sur repl.it .

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.