Покажіть п'ять найкращих результатів коментарів у публікації SE


30

Сценарій обміну стеками визначає, які п’ять коментарів на питання чи відповіді спочатку бачать на головній сторінці сайтів через кількість оновлень на них; відображаються п'ять коментарів з найбільшою кількістю голосів. Ваше завдання - відтворити таку поведінку.

Напишіть повну програму або функцію, беручи дані за допомогою STDIN, аргументів командного рядка або аргументів функції та друкує або повертає п'ять найкращих балів коментарів. Введенням буде масив цілих чисел, що представляють кількість оновлених коментарів до коментаря до якоїсь публікації. Наприклад, вхід

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

означає, що перший коментар не має голосів, другий має два голоси, третій - п'ять, четвертий - чотири і т. д. Порядок оцінок коментарів повинен залишатися однаковим у висновку.

Якщо вхід містить п'ять або менше балів коментарів, то вихід повинен містити не більше ніж наведені. Якщо два чи більше балів коментарів однакові, слід вивести перший бал (и). Ви можете припустити, що вхідний масив буде містити принаймні один бал коментарів.

Числа у висновку слід легко розрізнити (тому 02541 для випадку 1 недійсний). В іншому випадку немає обмежень на вихідний формат; номери можуть бути розділені пробілом або новим рядком, або вони можуть бути у форматі списку тощо.

Тестові приклади:

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

Останній приклад взяли з цього питання щодо переповнення стека .

Якщо можливо, надайте посилання у своєму дописі, де ваше подання може бути запущено в Інтернеті.

Це код гольфу, тому виграє найкоротший код у байтах. Удачі!


Повинен ми зберігати порядок?
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Так. Порядок появи цілих чисел не повинен змінюватися.
ТНТ

Відповіді:


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 байт

3 байти від спасибі @ user81655. 1 байт спасибі @apsillers.

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


5

Пітон 3, 76

Збережено 9 байт завдяки Кевіну, який нагадував мені, що я можу зловживати, якщо заяви в списку відповідають.

Збережено 5 байт завдяки DSM.

Досить просте рішення прямо зараз. Візьміть перші 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

05AB1E , 12 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

Пітон, 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 приймає введення як $a, а потім створює новий порожній хештель $b. Ми перебираємо всі елементи введення $a|%{...}та кожну ітерацію додаємо пару ключ / значення $b(робиться попереднім збільшенням хелперної змінної $dяк ключа для кожної ітерації). Тоді ми на sort $bоснові Value, то аст , а потім з допомогою (тобто ключ), і , нарешті , вихід тільки з результуючого хеша.select-l5sortName.Value

Якщо введено менше 5 елементів, воно буде просто сортувати за значенням, вибирати останні п'ять (тобто всі), пересортувати за клавішею та виводити.


Старіший, 120 байт, працює в більш ранніх версіях

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

Той самий алгоритм, що і відповідь Моргана Траппа , який, мабуть, є свідченням того, що великі уми думають однаково. :)

Здійснює введення даних, перевіряє, чи кількість елементів менша або рівна 5, і якщо так, виводиться вхід і виходить. В іншому випадку ми створюємо ArrayList $b(із непомірно довгим [System.Collections.ArrayList]складом) з п’яти найкращих елементів $a. Потім ми повторюємо $aі для кожного елемента, якщо він є, $bми виводимо його, а потім видаляємо його $b(і ось чому нам потрібно використовувати ArrayList, оскільки видалення елементів з масиву не підтримується функцією в PowerShell, оскільки вони технічно виправлені розмір).

Потрібна v3 або вище для -inоператора. Щоб відповісти, що працює в попередніх версіях, замініть $_-in$bна $b-contains$_загалом 126 байт .


2

Хаскелл, 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

Збережено 5 байт завдяки @WashingtonGuedes

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.
ТНТ

Здається, що для PHP 7.X поводиться по-різному, перемкніть версію PHP на 5.6 або нижче.
Самскванч

Отримав, не помітив номер версії. :)
ТНТ

Я не робив спочатку жодного. Я не впевнений, чому це не зберігає використану версію, а також код. Я також не впевнений, чому це не працює правильно 7.X.
Самскванч

@WashingtonGuedes Видалення пробілів врятувало мене 5 байтів, але я не бачу зайвих крапки з комою, які б не видали помилку?
Самскванч

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

Приємна програма. Вам, можливо, доведеться запитати про це в ОП. Я не впевнений, що формату введення нормально.
Rɪᴋᴇʀ

@RikerW насправді виходить із ладу, коли в останньому індексі є дублікат верхнього номера #, я зараз його змінюю
Джон

@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 1 і c 2 мають однакову кількість відгуків, але c 1 було розміщено раніше.

Це визначає загальну впорядкованість коментарів, а завдання, що знаходиться під рукою, - знайти п’ять коментарів, які мають найвищі переваги.

Замість того, щоб сортувати коментарі за пріоритетністю (що змінило б їх порядок, для кожного коментаря c ми підраховуємо коментарі, які мають більший або рівний пріоритет. Ми зберігаємо c, якщо і лише якщо цей підрахунок становить 5 чи менше.

Щоб частково сортувати коментарі за кількістю оновлень, робимо наступне. Нехай x - вектор стовпців, що містить підрахунок голосів. Тоді x'транспонований х - створюючи таким чином вектор - рядок - і x.<x'створює булеву матрицю , яка порівнює кожен елемент х з кожним елементом х Т .

Для 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)), ми розраховуємо кількість коментарів , які мають строго більше upvotes , ніж коментар в цьому індексі.

Для прикладу вектора це дає

4
2
0
1
4
3
4

Далі, ми підраховуємо кількість коментарів з рівною кількістю оновлень, опублікованих раніше, ніж цей коментар. Ми досягаємо цього наступним чином.

Спочатку ми будуємо таблицю рівності з x.==x', що compraes елементів х з елементами х Т . Для нашого прикладу вектор дає:

=     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

Необхідно відображати коментарі з пріоритетами від 1 до 5 , тому ми визначаємо їх індекси 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, і я думаю, що це достатньо інше, щоб бути цікавим.

Введення / виведення у формі кортежів. Перевірте це на repl.it .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.