## 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.

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)
```