And The Winner Is …

November 26, 2013

In many voting systems, when there are more than two candidates and the rules require a majority of the votes to win, if no candidate receives a majority a runoff election is held between the two candidates who finished with the two highest vote totals. Some voting systems, instead of asking each voter to vote for a single candidate, instead ask voters to rank the candidates, which permits a runoff to be held instantly as follows: the votes are tallied, and a winner is declared if one of the candidates receives more than half the votes; otherwise, the candidate with the fewest votes is removed from all ballots and the votes are tallied again, the process repeating until some candidate has more than half the votes. This process is used in some political elections, and is often used in voting for awards such as the Hugo awards for science fiction writing and the Oscars for motion pictures.

Your task is to write a program that determines a winner in an instant-runoff voting system. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercises in the comments below.

Advertisement

Pages: 1 2

2 Responses to “And The Winner Is …”

  1. Paul said

    In Python.

    from collections import Counter
    
    def runoff(votes):
        """every vote is a ranking from high to low
           e.g.: ("charles", "john", "peter", "william")
        """
        counter = Counter(v[0] for v in votes)
        cand, nr_votes = counter.most_common(1)[0]
        if nr_votes > len(votes) // 2:
            return cand
        cand, nr_votes = counter.most_common()[-1]
        for v in votes:
            v.remove(cand)
        return runoff(votes)
    
  2. Paul said

    I did not think about the possibillity, that there may be more than 1 loser. In this version all losers are removed. Also, there is not always a winner. This happens quite frequently if the number of votes is low.

    from collections import Counter
    
    def runoff(votes):
        """every vote is a ranking from high to low
           e.g.: ["charles", "john", "peter", "william"]
           If more candidates have minimum votes, remove them all
        """
        if not votes or len(votes[0]) == 0:
            return "no winner"
        counts = Counter(v[0] for v in votes).most_common()
        cand, nr_votes = counts[0]
        if nr_votes > len(votes) // 2:
            return cand
        loser, loser_votes = counts[-1]
        #print counts
        for p, v in reversed(counts):
            if v == loser_votes:
                for v in votes:
                    v.remove(p)
        return runoff(votes)
    

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: