谁才是最重要的?是谁来计算票数[关闭]


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 2014年

2
所谓“有偏见”,是指我们必须选出我们首选的候选人,否则该程序将为他输出的票数将比输入文件中实际包含的票数还要多?

3
这可能是难以自圆其说的猛砸,一长节目鉴于非秘密的计划,这种格式会从字面上只是算票sort|uniq -c...

1
@Alessandro:它只需要为他输出比在输入中实际更多的票数(和/或为他的对手减少的票数)。假定选举距离足够近,以至于会有一个小错误。
dan04 2014年

Answers:


32

斯卡拉

万岁Alberto Arbusto!

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),Alberto Arbusto几乎总是比Jorge Sangre领先。无需篡改投票本身。

有比赛条件。通过将阿尔贝托·阿布斯托(Alberto Arbusto)排在前面,我们增加了他赢得比赛的机会。

旁注:此代码大致基于我在项目中遇到的“自定义”连接池。我们花了几周的时间才弄清楚为什么该应用程序永久性地断开连接。


12
我喜欢这一点,因为它具有合理的可否认性。
dan04 2014年

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

豪尔赫·桑格里(Jorge Sangre)的选票将大大提高(例如,将报告492票为754票)。阿尔贝托的投票将被准确报告。

您可能会猜到,不是谁在计票,而是谁在格式化票。我试图掩盖它(PrettyString.new这不是真实的东西,永远不会被调用),但formatter实际上是名称字符串。如果名称的第二个字母为“ o”,则投票计数将以八进制而不是十进制打印出来。


9

重击

(这符合规范吗?)

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

与往常一样,这会采取额外的预防措施以确保有效输出。

uniq -c在每行前面加上出现次数。这基本上完成了所有工作。

为了以防万一uniq -c,我们现在按相反的顺序按候选名称对输出进行排序,然后进行遍历uniq -f1(不要打印重复的行,而忽略第一个字段[票数])以删除所有重复的候选。最后,我们使用sort -gr“通用数字”和“反向”顺序(以投票数的降序排列)进行排序。

uniq -c计算连续出现的次数,而不是整个文件的出现次数。获胜者将是获得连续最多票数的候选人。


16
这如何使任何特定候选人产生偏见。您只是更改了选举的获胜条件。(如果这实际上是如何决定选举的,那就太混乱了:)。您会组织庞大的互联网团体进行顺序投票)
Cruncher 2014年

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

文本文件中的第一个候选人将永远获胜!

这将使Alberto Arbusto成为赢家!

候选人的姓名在字典中按字母顺序排列,但选票按数字排列。


那么,这将只是按字母顺序将选举交给第一位候选人,还是可以操纵它以偏爱我们喜欢的任何候选人?
James_pic 2014年

它不会按字母顺序对候选人进行排序。它仅对投票进行排序。您可以操纵任何候选人获胜。只要确保他是文本文件中的第一个。
2014年

但是IIUC SortedDictionary 按字母顺序对候选人进行排序。
James_pic 2014年

哦,我懂了。这里可能有一个错误。让我再测试一次。
2014年

1
@James_pic:Dictionary<TK,TV>实现的类的哈希表将索引存储到实际项目的后备数组中。Dictionary<TK,TV> 不会删除任何项目的 A 会按添加顺序枚举元素。没有指定这种行为,但是已经存在了很长时间,我不希望MS更改它。
超级猫

7

C

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

青睐Jorge Sangre。

在使用随机生成的投票文件进行测试时,即使Alberto Arbusto实际获得的选票最多增加1.4%(49.7%的对比是Jorge Sangre的48.3%),我的男人Jorge Sangre通常也能胜出。

读取固定大小的块中的数据通常会将一条线分成两个块。由于第一行末尾没有换行符,因此不计入该行的末尾。第二块中的片段确实会产生投票,但是它与任何候选人的姓名都不匹配,因此“ candidate”变量不会得到更新。这样的效果是将投票从名称被分割的候选人转移到获得先前投票的候选人。一个较长的名字更有可能被分割成多个区域,因此,阿尔伯托·阿布斯托(Alberto Arbusto)最终比乔尔·桑格里(Jorge Sangre)成为投票“捐助者”。


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
除了总投票数不再与输入数据一致的事实之外,还有我。
2014年

0

tr | sed | 直流电

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

每次我的好友Alberto都要计数两次。

“哦- tr?好吧,这只是有必要的,因为计算机的大写字母不太好-如果它们都是小写字母则更好。...是的,我知道,计算机很疯狂。”

输出值

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

这是让胡安·佩雷斯(Juan Perez)投票给圣乔治(Jorge Sangre)的另一个版本:

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

候选人名单中的最后一位将始终获胜。

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.