在SE帖子上显示前5条评论分数


30

Stack Exchange脚本通过在站点上的投票数来确定最初在站点主页上看到的关于问题或答案的五个评论。将显示投票数最高的五个评论。您的任务是重新创建此行为。

编写完整的程序或函数,通过STDIN,命令行参数或函数参数输入,然后打印或返回前五个注释分数。输入将是一个整数数组,代表某个帖子的评论中的投票数。例如,输入

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

表示第一个评论没有投票,第二个评论有2票,第三个评论有5票,第四个有4票,依此类推。评论分数的顺序在输出中应该保持不变。

如果输入内容包含五个或更少的评论分数,则输出内容应只包含给定的分数。如果两个或更多评论分数相同,则应显示第一个分数。您可以假设输入数组将至少包含一个评论分数。

输出中的数字应易于区分(因​​此情况1的02541无效)。否则对输出格式没有限制;数字可以用空格或换行符分隔,也可以采用列表格式,等等。

测试用例:

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

最后一个示例来自此Stack Overflow问题

如果可能,请在您的帖子中提供一个链接,您可以在线运行您的提交。

这是代码高尔夫,因此以字节为单位的最短代码获胜。祝好运!


我们必须保留订单吗?
科纳·奥布莱恩

@CᴏɴᴏʀO'Bʀɪᴇɴ是的。整数出现的顺序不应更改。
TNT

Answers:


10

果冻,6 个字节

NỤḣ5Ṣị

在线尝试!一次验证所有测试用例

怎么运行的

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个字节

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

Ideone上进行测试

怎么运行的

list.remove从指定列表中删除其第一次出现的参数。通过反转列表x,我们实质上实现了它代替了最后一次出现。

因此,只要以最少的投票数就可以删除评论,直到列表不超过五个为止。然后,我们再次反转列表以恢复原始订单。


9

Pyth,11个字节

_.-_Q<SQ_5

我们计算输入(Q)与中的五个最大元素的多集交集Q(按它们在中出现的顺序Q),然后取其中的前五个。

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

在这里尝试。


<5SQ等于<SQ_5,节省1个字节。
PurkkaKoodari


有趣。我想知道为什么它没有实现为b[:-a]...我认为甚至在某个时候都可能是这样。
PurkkaKoodari

5

MATL,16字节

tn4>?t_FT#S5:)S)

这将使用当前版本(10.2.1),它比此挑战要早。

在线尝试!

说明

          % 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字节

感谢@ user81655,减少了3个字节。1字节的感谢@apsillers。

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


5

Python 3、76

感谢Kevin提醒我节省了9个字节,如果list列表中的语句会滥用。

DSM节省了5个字节。

现在非常简单的解决方案。抓住前5个得分,然后在列表中进行解析,找到它们后将它们添加到结果中。

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

如果有人需要,这是我的测试用例:

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

05AB1E12 11字节

码:

E[Dg6‹#Rß\R

说明:

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

使用CP-1252编码。


4

CJam,16个字节

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

一个未命名的块(函数),它接受一个数组并返回一个数组。

测试套件。

说明

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

Bash + GNU实用程序,36

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

通过STDIN / STDOUT将I / O格式化为以换行符分隔的列表。

在线尝试。


3

Python,68个字节

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

示例运行。

内置的块。我认为最好的解释方法是举一个例子。

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

enumerate将列表转换为索引/值对(从技术上讲是一个enumerate对象)。

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

这些对首先按照最大值进行排序,并保持当前索引的顺序。这是评分最高的评论,该评论被较早的帖子打破。然后,采用5条最佳评论。

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

将前五个注释按发布顺序放回去,然后删除索引,仅保留分数。


3

PowerShell的V4,120个 97字节

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

经过试验,我发现了一种替代方法,可以减少一些额外的字节。但是,它似乎特定于PowerShell v4以及该版本如何处理哈希表的排序-默认情况下,似乎在v4中,如果多个值具有相同的值,它将使用带有“低”键的值。您无法保证在v3或更早版本中,即使使用命令在v3中关键字关键字。我尚未针对PowerShell v5对此进行全面审查,以说明行为是否继续。

此仅v4版本将input作为输入$a,然后创建一个新的空hashtable $b。我们遍历输入的所有元素,$a|%{...}每次迭代都添加一个键/值对$b(通过预增加一个辅助变量$d作为每次迭代的键来完成)。然后,我们sort $b基于Value,然后select-last 5,然后是sort根据Name(即键),最后仅输出.Value结果哈希 s。

如果输入的元素少于5个,它将仅按值排序,选择最后五个(即全部),按键重新排序并输出。


较旧的120字节,可在较早版本中使用

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

与Morgan Thrapp的答案相同的算法,这显然表明了伟大的思想家也是如此。:)

进行输入,检查项目数是否小于或等于5,如果是,则输出输入并退出。否则,我们将创建的前五个元素的ArrayList $b(具有冗长的转换[System.Collections.ArrayList]$a。然后,我们遍历$a每个元素,如果存在,则将其$b输出,然后从中删除$b(这就是为什么我们需要使用ArrayList的原因,因为从数组中删除元素在PowerShell中不受支持,因为它在技术上是固定的尺寸)。

要求v​​3或更高版本-in。对于在早期版本的Works,交换答案$_-in$b$b-contains$_总共126个字节


2

Haskell,62个字节

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

用法示例: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]

工作原理:使用索引增加每个元素,对元素进行降序排序,采用前5个元素,按索引排序并删除索引。


2

PHP 5,107 102

@WashingtonGuedes节省了5个字节

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

不打高尔夫球

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

试试吧。


对于1 1 5 1 1 5,您的提交将产生的输出,1 5 1 1 5而不是正确的输出1 1 5 1 5
TNT

对于PHP 7.X,它的行为似乎有所不同,请将PHP版本切换到5.6或更低版本。
Samsquanch '16

知道,没有注意到版本号。:)
TNT

一开始我也没有。我不确定为什么不保存使用的版本以及代码。我也不确定为什么它不能在7.X上正常工作。
Samsquanch '16

@WashingtonGuedes删除空格为我节省了5个字节,但是我看不到任何不必要的分号不会引发错误?
Samsquanch '16

0

红宝石,82 87 89字节

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

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

原始提交-56个字节,但在某些测试用例上失败,并且不支持$ stdin和$ stdout

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

说明

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

不错的程序。您可能需要向OP询问。我不确定输入格式是否正确。
Rɪᴋᴇʀ

@RikerW当最后一个索引中有重复的top#时,它实际上会失败,我现在正在对其进行修改
John

@RikerW现在已修复,它支持stdin并写入stdout。
约翰

好的。我喜欢输入法。我只是说要问@TNT。
Rɪᴋᴇʀ

0

Java 7,155个字节

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

取消测试&测试代码:

在这里尝试。

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

输出:

[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

朱莉娅,48个字节

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

在线尝试!

怎么运行的

如果满足以下条件之一,则注释c 1的优先级高于注释c 2

  • c 1的投票比c 2的投票更多。
  • c 1c 2具有相同数量的投票,但c 1是较早发布的。

这定义了注释的总顺序,当前的任务是找到优先级最高的五个注释。

而不是按优先级对注释进行排序(这将改变它们的顺序,对于每个注释c,我们都计算优先级更高或相等的注释。当且仅当此计数等于或小于5时,我们才保留c

要按投票数对评论进行部分排序,请执行以下操作。令x为包含投票计数的列向量。然后x'转置x-从而创建行向量-并x.<x'创建一个布尔矩阵,该矩阵将x的每个元素与x T的每个元素进行比较

对于x = [0,2,5,4,0,1,0],得出

<     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

通过跨行求和(通过sum(...,2)),我们计算出比该索引处的评论严格具有更多投票的评论数。

对于示例向量,这给出了

4
2
0
1
4
3
4

接下来,我们计算比该评论更早发布的评论数量相等的评论数。我们实现如下。

首先,我们用建立一个相等表x.==x',该表将x的元素与x T的元素进行比较。对于我们的示例向量,它给出:

=     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

接下来,我们用于cumsum计算矩阵各列的累积和。

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

对角线(diag)保存具有相等赞成数并且不迟于相应注释出现的注释数量。

1
1
1
1
2
1
3

通过将我们产生的两个行向量相加,我们可以获得注释的优先级(最高为1)。

5
3
1
2
6
4
7

应该显示优先级为15的注释,因此我们用确定索引,find(....<6)并使用检索相应的注释x[...]


0

Python 3.5,68个字节

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

我的Python 2答案不匹配,但仅比其与Python 3的端口长三个字节,我认为它的区别足以引起人们的兴趣。

I / O是元组的形式。在repl.it对其进行测试。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.