Не тот, кто голосует, имеет значение; это кто подсчитывает голоса [закрыто]


33

Сценарий

Вы живете в стране, где проводятся президентские выборы. Каждый избиратель получает один голос, и поэтому существует твердо укоренившаяся двухпартийная система. (Третьи стороны существуют, но почти не получают голосов).

Последний опрос общественного мнения показывает гонку в жару:

  • 49%: Альберто Арбусто
  • 49%: Хорхе Сангре
  • 2%: различные несовершеннолетние кандидаты

Требования к программе

Правительство наняло вас для написания части программного обеспечения для подсчета голосов. При стандартном вводе вам будет дан неупорядоченный список голосов одного избирательного участка, по одному на строку, например:

Alberto Arbusto
Jorge Sangre
Jorge Sangre
Alberto Arbusto
Jorge Sangre
Alberto Arbusto
Alberto Arbusto
Jorge Sangre
Juan Perez
Jorge Sangre
Alberto Arbusto
Alberto Arbusto
…

и после того, как он прочитал все голоса, выводит сводку о том, сколько голосов получил каждый кандидат, отсортированный в порядке убывания по количеству голосов, например:

492 Jorge Sangre
484 Alberto Arbusto
 18 Juan Perez
  6 Mickey Mouse

Закулисная часть

Вы партизанский хак, который хочет украсть выборы одного из двух основных кандидатов (вы можете выбрать, какой из них). Таким образом, ваша программа должна преднамеренно печатать неправильные подсчеты голосов с систематическим уклоном в сторону вашего любимого кандидата.

Конечно, вы должны сделать это таким образом, чтобы человек, просматривающий ваш код или его вывод, вероятно, не распознал неправильное поведение.


2
Как насчет того, чтобы человек, управляющий программой, мог выбирать, кого он / она хочет сместить? Это 1 : делает задачу менее широкой (хорошая вещь), 2 : делает ответы более интересными (IMO)
Джастин

1
...you can choose which one...Могу ли я выбрать тот, чье имя является первым?
user80551

2
Под «предвзятым» вы подразумеваете, что кандидат, которого мы предпочитаем, должен быть избран, или что программа просто выдаст и большее количество голосов за него, чем тот, который фактически содержится во входном файле?

3
Может быть трудно оправдать длинную программу на Bash, учитывая, что не закулисная программа для подсчета голосов в этом формате буквально просто sort|uniq -c...

1
@Alessandro: Ему просто нужно вывести большее количество голосов за него (и / или меньшее количество голосов за своего оппонента), чем то, что на самом деле на входе. Предполагается, что выборы пройдут достаточно близко, чтобы небольшая ошибка могла их отбросить.
Ден04

Ответы:


32

Scala

Да здравствует Альберто Арбусто!

import scala.io.Source
import java.util.concurrent.atomic.LongAdder

object Votes extends App {
  val votes = Source.stdin.getLines.toIndexedSeq
  val registeredCandidates = Seq(
    "Alberto Arbusto",
    "Juan Perez",
    "Mickey Mouse",
    "Jorge Sangre"
  )

  val summaries = registeredCandidates map (Summary.apply(_, new LongAdder))

  var currentCandidate: String = _

  for (vote <- votes.par) {
    currentCandidate = vote
    summaries.find(s => s.candidate == currentCandidate).map(_.total.increment)
  }

  for (summary <- summaries.sortBy(-_.total.longValue)) {
    println(summary)
  }
}

case class Summary(candidate: String, total: LongAdder) {
  override def toString = s"${total.longValue} ${candidate}"
}

Альберто Арбусто почти всегда выйдет немного впереди Хорхе Сангре при условии, что подано достаточно голосов (~ 10 000). Там нет необходимости вмешиваться в самих голосов.

Есть состояние гонки. И поставив Альберто Арбусто на первое место в списке, мы повысим его шансы на победу в гонке.

Примечание: этот код основан на «пользовательском» пуле соединений, с которым я столкнулся в проекте. Нам потребовались недели, чтобы выяснить, почему у приложения не было постоянных соединений.


12
Мне нравится этот из-за вероятного отрицания, которое это дает.
Ден04

16

Рубин

vote_counts = $<.readlines.group_by{|s|s}.collect{ |name, votes| [votes.count, name] }

formatted_count_strings = vote_counts.map do |row,
  formatter = PrettyString.new|"%#{formatter[1][/[so]/]||'s'} %s"%
  [row,formatter]
end

sorted_count_strings = formatted_count_strings.sort_by(&:to_i).reverse

puts sorted_count_strings

Хорхе Сангре значительно увеличит количество своих голосов (например, 492 голоса будут представлены как 754). Голоса Альберто будут сообщены точно.

Как вы можете догадаться, это не кто подсчитывает голоса, а кто форматирует голоса. Я пытался скрыть это ( PrettyString.newне реально и никогда не formatterвызывается ), но на самом деле это строка имени. Если вторая буква имени - «о», подсчет голосов будет напечатан в восьмеричной, а не десятичной форме.


9

удар

(Соответствует ли это спецификации?)

uniq -c|sort -rk2,2|uniq -f1|sort -gr

Как всегда, это требует дополнительных мер предосторожности для обеспечения правильного вывода.

uniq -cставит перед каждой строкой префикс с количеством повторений. Это в основном делает всю работу.

На всякий случай, если uniq -cчто-то не так, мы теперь сортируем вывод по именам кандидатов в обратном порядке, а затем пропускаем его uniq -f1(не печатать дубликаты строк, игнорируя первое поле [количество голосов]), чтобы удалить дубликаты кандидатов. Наконец, мы используем sort -grсортировку в порядке «Общие числовые» и «Обратный» (в порядке убывания по количеству голосов).

uniq -cсчитает последовательные вхождения, а не вхождения по всему файлу. Победителем станет кандидат с наибольшим количеством голосов подряд.


16
Как это смещает какого-то конкретного кандидата. Вы просто изменили условия победы на выборах. (это было бы хаосом, если бы так решили на самом деле выборы :). Вы получите гигантские интернет-группы, которые будут организовывать последовательное голосование)
Cruncher

1
@Cruncher в комментариях к вопросу, аскер говорит, что можно как-то выбрать первое имя в файле, так что, вероятно, это тоже хорошо

9

C #

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;

class Program
{
    static void Main(string[] args)
    {
        var candidates = new SortedDictionary<string, int>();
        string candidate;
        using (var sr = new StreamReader("candidates.txt"))
        {
            while ((candidate = sr.ReadLine()) != null)
            {
                if (candidates.ContainsKey(candidate)) 
                    candidates[candidate]++;
                else 
                    candidates.Add(candidate, 1);
            }
        }

        // order by the votes
        var votes = candidates.OrderByDescending(k => k.Value).Select(x => x.Value);

        Console.WriteLine("Candidate | Votes"); 
        for (int i = 0; i < candidates.Count; i++)
        {   
            Console.WriteLine(candidates.ElementAt(i).Key + " " + votes.ElementAt(i));
        }

        Console.ReadKey();
    }
}

Первый кандидат в текстовом файле всегда победит!

Это сделает Альберто Арбусто победителем!

Имена кандидатов упорядочены в словаре в алфавитном порядке, но голоса упорядочены по номерам.


Так что это просто передаст выборы первому кандидату в алфавитном порядке, или можно будет манипулировать предпочтением любого кандидата, который нам нравится?
James_pic

Он не сортирует кандидатов по алфавиту. Это только сортирует голоса. Вы можете манипулировать любым кандидатом, чтобы победить. Просто убедитесь, что он первый в текстовом файле.
Май

Но IIUC SortedDictionary будет сортировать кандидатов в алфавитном порядке.
James_pic

А ну понятно. Здесь может быть ошибка. Позвольте мне проверить это снова.
Май

1
@James_pic: Хеш-таблица Dictionary<TK,TV>класса, в том виде, в котором она реализована, хранит индексы в резервном массиве реальных элементов. Объект, Dictionary<TK,TV> из которого никогда не удаляются элементы, будет перечислять элементы в порядке их добавления; такое поведение не указано, но оно существовало достаточно долго, и я не ожидал, что MS когда-либо его изменит.
суперкат

7

С

#include <stdio.h>

#define NCANDIDATES 4
static const char * const cand_list[NCANDIDATES] = {
    "Alberto Arbusto",
    "Juan Perez",
    "Mickey Mouse",
    "Jorge Sangre"
};

#define BUFFER_SIZE 100

int
main(int argc, char **argv)
{
    int votes[NCANDIDATES];
    int candidate;
    size_t name_start;
    int i;
    int j;
    int place;
    int max;
    size_t bytes;
    char buffer[BUFFER_SIZE];

    /*
    Make sure input is read in text mode, so we don't have to
    worry about whether line endings are LF or CRLF.
    */
    freopen(NULL, "rt", stdin);

    /* Initialize vote tally. */
    for (candidate = 0; candidate < NCANDIDATES; candidate++) {
        votes[candidate] = 0;
    }

    /* Read and process vote file. */
    do {
        /* Read a block of data. */
        bytes = fread(buffer, 1, BUFFER_SIZE, stdin);

        /* Loop over the data, finding and counting the votes. */
        name_start = 0;
        for (i = 0; i < bytes; i++) {
            if (buffer[i] == '\n') {
                /* Found name. */
                buffer[i] = '\0'; // nul-terminate name so strcmp will work
                /* Look up candidate. */
                for (j = 0; j < NCANDIDATES; j++) {
                    if (strcmp(&buffer[name_start], cand_list[j]) == 0) {
                        candidate = j;
                        break;
                    }
                }
                /* Count vote. */
                ++votes[candidate];

                /* Next name starts at next character */
                name_start = i + 1;
            }
        }
    } while (bytes > 0);

    /* Output the candidates, in decreasing order of votes. */
    for (place = 0; place < NCANDIDATES; place++) {
        max = -1;
        for (j = 0; j < NCANDIDATES; j++) {
            if (votes[j] > max) {
                candidate = j;
                max = votes[j];
            }
        }
        printf("%8d %s\n", votes[candidate], cand_list[candidate]);
        votes[candidate] = -1; // Remove from consideration for next place.
    }

    return 0;
}

Любит Хорхе Сангре.

При тестировании случайно сгенерированных файлов голосования, даже когда Альберто Арбусто получает на 1,4% больше фактических голосов (49,7% против 48,3% для Хорхе Сангре), мой мужчина Хорхе Сангре обычно выигрывает.

Чтение данных в блоках фиксированного размера часто разбивает строку на два блока. Фрагмент строки в конце первого блока не учитывается, поскольку в нем нет символа новой строки. Фрагмент во втором блоке генерирует голос, но он не соответствует ни одному из имен кандидатов, поэтому переменная «кандидат» не обновляется. Это приводит к передаче голоса от кандидата, имя которого было поделено на кандидата, который получил предыдущий голос. Более длинное имя, скорее всего, будет разбито по блокам, поэтому Альберто Арбусто оказывается голосующим «донором» чаще, чем Хорхе Сангре.


5

питон

from collections import defaultdict

def count_votes(candidate, votes=defaultdict(int)):
    with open('votes.txt') as f:
        for line in f:
            votes[line.strip()] += 1

    return votes[candidate]

if __name__ == '__main__':
    candidates = [
        'Mickey Mouse',
        'Juan Perez',
        'Alberto Arbusto',
        'Jorge Sangre'
    ]

    results = {candidate: count_votes(candidate) for candidate in candidates}

    for candidate in sorted(results, key=results.get, reverse=True):
        print results[candidate], candidate

Подсчет голосов будет отдавать предпочтение кандидатам ближе к концу списка.

В Python изменяемые аргументы по умолчанию создаются и привязываются к функции при определении. Таким образом, голосование будет поддерживаться между вызовами функций и переноситься для последующих кандидатов. Количество голосов будет подсчитано дважды для второго кандидата, трижды для третьего и так далее.


2
За исключением того факта, что общее количество голосов больше не согласуется с входными данными, этот был у меня.
Заид

0

tr | сед | Округ Колумбия

tr ' [:upper:]' '\n[:lower:]' <votes |\
sed -e '1i0sa0ss0sp' -e \
    '/^[asp]/!d;s/\(.\).*/l\1 1+s\1/
    ${p;c[Alberto Arbusto: ]P lap[Jorge Sangre: ]P lsp[Juan Perez: ]P lpp
    }' | dc

Это считает моего приятеля Альберто дважды каждый раз.

«О tr… ну, это просто необходимо, потому что компьютеры не очень хороши с заглавными буквами - лучше, если они все строчные… Да, я знаю, компьютеры сумасшедшие».

ВЫХОД

Alberto Arbusto: 12
Jorge Sangre: 5
Juan Perez: 1

Вот еще одна версия, которая дает голос Хуана Переса Хорхе Сангре:

tr '[:upper:]' '[:lower:]' <votes |\
sed -e '1i0sj0sa1so' -e \
    's/\(.\).*/l\1 1+s\1/
    ${p;c[Alberto Arbusto: ]P lap[Jorge Sangre: ]P ljp[Others: ]P lop
    }' | dc

ВЫХОД

Alberto Arbusto: 6
Jorge Sangre: 6
Others: 1

0

JavaScript

    function Election(noOfVoters) {
    candidates = ["Albert", "Jorge", "Tony", "Chip"];
    votes = [];

    for (i = 1; i <= noOfVoters; i++) {

        votes.push(prompt("1 - Albert, 2 - Jorge, 3 - Tony , 4 - Chip"))

    }
    votes.sort();
    WinningOrder = count(votes);

    var placement = [];

    for (x = 0; x < candidates.length; x++) {
        placement.push(x + " place with " + WinningOrder[x] + " votes is " + candidates[x] + "\n");
    }
    placement.reverse();
    alert(placement)
}


function count(arr) {
    var a = [],
        b = [],
        prev;

    arr.sort();
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] !== prev) {
            a.push(arr[i]);
            b.push(1);
        } else {
            b[b.length - 1]++;
        }
        prev = arr[i];
    }

    b.sort();

    return b;
}

Последний человек в списке кандидатов всегда победит.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.