ไม่ใช่ผู้ลงคะแนนที่นับ มันคือใครนับคะแนน [ปิด]


33

สถานการณ์

คุณอาศัยอยู่ในประเทศที่มีการเลือกตั้งประธานาธิบดี ผู้มีสิทธิเลือกตั้งแต่ละคนจะได้รับหนึ่งคะแนนและดังนั้นจึงมีระบบสองพรรคที่มั่นคง (มีบุคคลที่สามอยู่ แต่ไม่ได้รับคะแนนใด ๆ เลย)

แบบสำรวจความคิดเห็นล่าสุดแสดงให้เห็นว่าการแข่งขันในความร้อนที่ตาย:

  • 49%: Alberto Arbusto
  • 49%: Jorge Sangre
  • 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)
Justin

1
...you can choose which one...ฉันสามารถเลือกชื่อที่มีชื่อแรกได้หรือไม่?
user80551

2
โดย "ลำเอียง" คุณหมายถึงว่าผู้สมัครที่เราต้องการจะต้องได้รับการเลือกตั้งหรือไม่ก็ตามโปรแกรมจะส่งออกและให้คะแนนจำนวนที่สูงกว่าเขามากกว่าที่มีอยู่ในไฟล์อินพุตจริงหรือ

3
มันอาจเป็นเรื่องยากที่จะแสดงให้เห็นถึงโปรแกรมที่ยาวนานใน Bash เนื่องจากโปรแกรมที่ไม่ได้ใช้เล่ห์เหลี่ยมในการนับคะแนนในรูปแบบนี้จะเป็นตัวอักษรsort|uniq -cจริงๆ ...

1
@ อเลสซานโดร: มันแค่เอาท์พุทจำนวนโหวตที่สูงขึ้นสำหรับเขา (และ / หรือจำนวนโหวตที่ต่ำกว่าสำหรับคู่ต่อสู้ของเขา) มากกว่าสิ่งที่อยู่ในอินพุท การเลือกตั้งจะอยู่ใกล้พอที่จะทำให้เกิดข้อผิดพลาดเล็กน้อย
dan04

คำตอบ:


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 ก่อนหน้านี้ในรายการเราเพิ่มโอกาสในการชนะการแข่งขัน

หมายเหตุด้านข้าง: รหัสนี้ขึ้นอยู่กับพูลการเชื่อมต่อแบบ "กำหนดเอง" ที่ฉันพบในโครงการ เราใช้เวลาหลายสัปดาห์ในการหาสาเหตุที่ทำให้แอปพลิเคชันหลุดจากการเชื่อมต่อตลอดเวลา


12
ฉันชอบอันนี้เพราะความน่าจะเป็นที่จะเป็นไปได้
dan04

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

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

มันไม่เรียงลำดับตัวอักษรของผู้สมัคร เพียงเรียงลำดับคะแนนเท่านั้น คุณสามารถจัดการกับผู้สมัครที่จะชนะ เพียงให้แน่ใจว่าเขาเป็นคนแรกในไฟล์ข้อความ
mai

แต่ IIUC SortedDictionary จะเรียงลำดับผู้สมัครตามตัวอักษร
James_pic

อ้อเข้าใจแล้ว. อาจมีข้อผิดพลาดที่นี่ ขอผมทดสอบอีกที
mai

1
@James_pic: ตารางแฮชของDictionary<TK,TV>คลาสตามการนำไปใช้จะจัดเก็บดัชนีไว้ในอาร์เรย์สำรองของรายการจริง A Dictionary<TK,TV> ที่ไม่มีรายการใดถูกลบจะระบุองค์ประกอบตามลำดับที่ถูกเพิ่มเข้าไป ไม่ได้ระบุพฤติกรรมดังกล่าว แต่ใช้เวลานานพอสมควรที่ฉันจะไม่คาดหวังให้ MS เปลี่ยนพฤติกรรม
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;
}

Jorge Sangre โปรดปราน

ในการทดสอบกับไฟล์โหวตที่สร้างแบบสุ่มแม้ว่า Alberto Arbusto จะได้รับคะแนนเสียงจริงมากขึ้น 1.4% (49.7% เทียบกับ 48.3% สำหรับ Jorge Sangre) Jorge Sangre คนของฉันมักชนะการนับคะแนน

การอ่านข้อมูลในบล็อกที่มีขนาดคงที่มักจะแบ่งบรรทัดออกเป็นสองบล็อก แฟรกเมนต์ของส่วนท้ายของบล็อกแรกจะไม่ถูกนับเนื่องจากไม่มีอักขระขึ้นบรรทัดใหม่ ส่วนในบล็อกที่สองสร้างการลงคะแนน แต่ไม่ตรงกับชื่อของผู้สมัครใด ๆ ดังนั้นตัวแปร 'ผู้สมัคร' จึงไม่ได้รับการอัปเดต นี่เป็นผลของการถ่ายโอนการโหวตจากผู้สมัครที่มีชื่อถูกแบ่งเป็นผู้สมัครที่ได้รับการโหวตก่อนหน้านี้ ชื่อที่ยาวกว่ามีแนวโน้มที่จะถูกแบ่งข้ามบล็อกดังนั้น 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
ยกเว้นความจริงที่ว่าจำนวนการลงคะแนนทั้งหมดนั้นไม่สอดคล้องกับข้อมูลอินพุตอีกต่อไปสิ่งนี้มีฉัน
Zaid

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

คนสุดท้ายในรายชื่อผู้สมัครจะชนะเสมอ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.