Đó không phải là người bỏ phiếu mà tính; đó là người đếm phiếu [đã đóng]


33

Kịch bản

Bạn sống ở một đất nước đang có cuộc bầu cử tổng thống. Mỗi cử tri được một phiếu bầu, và do đó có một hệ thống hai đảng cố thủ vững chắc. (Các bên thứ ba tồn tại, nhưng hầu như không nhận được bất kỳ phiếu bầu nào).

Cuộc thăm dò ý kiến ​​mới nhất cho thấy cuộc đua trong một cái chết nóng:

  • 49%: Alberto Arbusto
  • 49%: Jorge Sangre
  • 2%: nhiều ứng cử viên nhỏ

Các yêu cầu của chương trình

Bạn đã được chính phủ thuê để viết một phần của phần mềm kiểm phiếu. Bạn sẽ được cung cấp, trên đầu vào tiêu chuẩn, một danh sách không có thứ tự gồm một phiếu bầu của khu bầu cử, mỗi phiếu trên một dòng, như thế này:

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

và, sau khi đọc tất cả các phiếu bầu, đưa ra một bản tóm tắt về số lượng phiếu mà mỗi ứng cử viên nhận được, được sắp xếp theo thứ tự giảm dần theo số phiếu, như thế này:

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

Phần lót tay

Bạn là một đảng phái muốn đánh cắp cuộc bầu cử cho một trong hai ứng cử viên chính (bạn có thể chọn ứng cử viên nào). Vì vậy, chương trình của bạn phải cố tình in số phiếu không chính xác , với sự thiên vị có hệ thống đối với ứng cử viên yêu thích của bạn.

Tất nhiên, bạn phải làm điều này theo cách mà một người nhìn vào mã của bạn hoặc đầu ra của mã có thể không nhận ra hành vi không chính xác.


2
Làm thế nào về việc để người điều hành chương trình chọn người mà anh ấy / cô ấy muốn thiên vị? Điều này 1 : làm cho thử thách bớt rộng hơn (một điều tốt), 2 : làm cho câu trả lời trở nên thú vị hơn (IMO)
Justin

1
...you can choose which one...Tôi có thể chọn tên có tên đầu tiên không?
dùng80551

2
Bằng cách "thiên vị", bạn có nghĩa là ứng cử viên chúng tôi muốn được bầu, hoặc chương trình sẽ đơn giản xuất ra và số phiếu bầu cao hơn cho anh ta so với ứng cử viên thực sự có trong tệp đầu vào?

3
Có thể rất khó để biện minh cho một chương trình dài ở Bash, vì một chương trình không được sử dụng để đếm phiếu theo định dạng này theo nghĩa đen sẽ chỉ là sort|uniq -c...

1
@Alessandro: Đơn giản chỉ cần xuất ra số phiếu bầu cao hơn cho anh ta (và / hoặc số phiếu bầu thấp hơn cho đối thủ của anh ta) so với những gì thực sự có trong đầu vào. Cuộc bầu cử được cho là đủ gần để một lỗi nhỏ có thể cuốn trôi nó.
dan04

Câu trả lời:


32

Scala

Sống lâu với 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}"
}

Alberto Arbusto hầu như sẽ luôn xuất hiện một chút trước Jorge Sangre, với điều kiện đủ số phiếu được bỏ ra (~ 10.000). Không cần phải can thiệp vào số phiếu.

Có một điều kiện chủng tộc. Và bằng cách đưa Alberto Arbusto sớm hơn vào danh sách, chúng tôi tăng cơ hội chiến thắng cuộc đua của anh ấy.

Lưu ý bên lề: Mã này dựa trên nhóm kết nối "tùy chỉnh" mà tôi gặp trong một dự án. Chúng tôi đã mất nhiều tuần để tìm ra lý do tại sao ứng dụng này liên tục bị mất kết nối.


12
Tôi thích cái này vì sự từ chối hợp lý mà nó mang lại.
dan04

16

Hồng ngọc

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 sẽ có được sự gia tăng đáng kể về số phiếu bầu của mình (ví dụ: 492 phiếu sẽ được báo cáo là 754). Phiếu bầu của Alberto sẽ được báo cáo chính xác.

Như bạn có thể đoán, không phải ai là người kiểm phiếu mà là người định dạng phiếu. Tôi đã cố làm mờ nó ( PrettyString.newkhông phải là đồ thật và không bao giờ được gọi), nhưng formatterthực ra là chuỗi tên. Nếu chữ cái thứ hai của tên là 'o', số phiếu sẽ được in ra bằng số bát phân thay vì số thập phân.


9

Bash

(Điều này có đáp ứng các đặc điểm kỹ thuật không?)

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

Như mọi khi, điều này có thêm biện pháp phòng ngừa để đảm bảo đầu ra hợp lệ.

uniq -ctiền tố mỗi dòng với số lần nó xảy ra. Điều này về cơ bản làm tất cả các công việc.

Trong trường hợp uniq -ccó gì đó không đúng, bây giờ chúng tôi sắp xếp đầu ra của nó theo tên của các ứng cử viên theo thứ tự ngược lại, sau đó chạy qua uniq -f1(không in các dòng trùng lặp, bỏ qua trường đầu tiên [số phiếu] để loại bỏ bất kỳ ứng cử viên trùng lặp nào. Cuối cùng, chúng tôi sử dụng sort -grđể sắp xếp theo thứ tự "Số chung" và "Đảo ngược" (thứ tự giảm dần theo số phiếu).

uniq -cđếm số lần xuất hiện liên tiếp, không xuất hiện trên toàn bộ tập tin. Người chiến thắng sẽ là ứng cử viên có nhiều phiếu bầu liên tiếp nhất.


16
Làm thế nào để thiên vị bất kỳ ứng cử viên cụ thể. Bạn chỉ đơn giản là thay đổi điều kiện chiến thắng của cuộc bầu cử. (điều này sẽ là hỗn loạn nếu đây là cách mà cuộc bầu cử đã được quyết định thực sự :). Bạn sẽ nhận được các nhóm internet khổng lồ tổ chức bỏ phiếu liên tục)
Cruncher

1
@Cruncher trong các bình luận về câu hỏi, người hỏi nói rằng thật tốt khi chọn tên đầu tiên trong tệp bằng cách nào đó, vì vậy điều này có lẽ cũng tốt

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

Ứng cử viên đầu tiên trong tập tin văn bản sẽ luôn giành chiến thắng!

Nó sẽ làm cho Alberto Arbusto trở thành người chiến thắng!

Tên của các ứng cử viên được sắp xếp theo thứ tự abc trong từ điển, nhưng phiếu bầu được sắp xếp theo số.


Vì vậy, điều này sẽ trao cuộc bầu cử cho ứng cử viên đầu tiên theo thứ tự abc, hoặc nó có thể được thao túng để thích bất kỳ ứng cử viên nào chúng ta thích?
James_pic

Nó không sắp xếp các ứng cử viên theo thứ tự abc. Nó chỉ sắp xếp các phiếu bầu. Bạn có thể thao túng bất kỳ ứng cử viên nào để giành chiến thắng. Chỉ cần chắc chắn rằng anh ta là người đầu tiên trong tệp văn bản.
mai

Nhưng IIUC SortedDictionary sẽ sắp xếp các ứng cử viên theo thứ tự abc.
James_pic

Ồ, tôi hiểu rồi. Có thể có một sai lầm ở đây. Hãy để tôi kiểm tra lại.
mai

1
@James_pic: Bảng băm của Dictionary<TK,TV>lớp, như được triển khai, lưu trữ các chỉ mục vào một mảng sao lưu của các mục thực tế. Một Dictionary<TK,TV> từ đó có mặt hàng nào được bao giờ bị xóa sẽ liệt kê các yếu tố theo thứ tự chúng được bổ sung; hành vi như vậy không được chỉ định, nhưng nó đã diễn ra đủ lâu rồi tôi sẽ không mong đợi MS sẽ thay đổi nó.
supercat

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

Ủng hộ Jorge Sangre.

Trong thử nghiệm với các tệp phiếu bầu được tạo ngẫu nhiên, ngay cả khi Alberto Arbusto nhận được nhiều hơn 1,4% số phiếu thực tế (49,7% so với 48,3% cho Jorge Sangre), người đàn ông của tôi, ông Jorge Sangre thường giành chiến thắng.

Đọc dữ liệu trong các khối có kích thước cố định thường chia một dòng trên hai khối. Đoạn của dòng ở cuối khối đầu tiên không được tính vì nó không có ký tự dòng mới. Đoạn trong khối thứ hai sẽ tạo ra một phiếu bầu, nhưng nó không khớp với bất kỳ tên nào của ứng cử viên để biến 'ứng cử viên' không được cập nhật. Điều này có tác dụng chuyển một phiếu bầu từ ứng cử viên có tên được chia cho ứng cử viên đã nhận được phiếu bầu trước đó. Một cái tên dài hơn có nhiều khả năng được phân chia thành các khối, do đó, Alberto Arbusto cuối cùng trở thành một "nhà tài trợ" bỏ phiếu thường xuyên hơn so với Jorge Sangre.


5

Con trăn

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

Số phiếu sẽ ủng hộ các ứng cử viên gần hơn đến cuối danh sách.

Trong Python, các đối số mặc định có thể thay đổi được tạo và ràng buộc với hàm theo định nghĩa. Vì vậy, phiếu bầu sẽ được duy trì giữa các cuộc gọi chức năng và được chuyển cho các ứng cử viên tiếp theo. Số phiếu sẽ được tính hai lần cho ứng cử viên thứ hai, ba lần cho người thứ ba, v.v.


2
Ngoại trừ thực tế là tổng số phiếu không còn phù hợp với dữ liệu đầu vào, cái này có tôi.
Zaid

0

tr | sed | đc

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

Điều này đếm bạn thân của tôi hai lần mỗi lần.

"Ồ - tr? Chà, nó chỉ cần thiết vì máy tính không tốt bằng chữ in hoa - tốt hơn nếu tất cả đều là chữ thường .... Vâng, tôi biết, máy tính thật điên rồ."

ĐẦU RA

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

Đây là một phiên bản khác mang lại phiếu bầu của Juan Perez cho 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

ĐẦU RA

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

Người cuối cùng trong danh sách ứng cử viên sẽ luôn giành chiến thắng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.