Skip to content

Commit

Permalink
Don't consider spoiled ballots in candidate consideration after deter…
Browse files Browse the repository at this point in the history
…mining

number, also factoring out common tie-breaking code
  • Loading branch information
James Cash committed Sep 19, 2009
1 parent 5d3e972 commit 3df4924
Showing 1 changed file with 15 additions and 6 deletions.
21 changes: 15 additions & 6 deletions app/helpers/application_helper.rb
Expand Up @@ -18,27 +18,36 @@ def calculate_winner_preferential election
if spoiled > total/2.0
return [:spoiled , spoiled] # How do we want to indicate this?
end

# For most of the next calculations, we only want actual candidates, i.e. not spoiled ballots
real_candidates = candidates.reject {|k,v| k == 0 }

# Find the candidates with the most and least votes
leader_id, leader_votes = real_candidates.max { |a,b| a[1] <=> b[1] }
loser_id, loser_votes = real_candidates.min { |a,b| a[1] <=> b[1] }

leader_id, leader_votes = candidates.max { |a,b| a[1] <=> b[1] }
loser_id, loser_votes = candidates.min { |a,b| a[1] <=> b[1] }
resolve_tie = lambda do # have to use a lambda to capture variables in the outer scope
# Currently just return all the tied candidates
tied = real_candidates.select { |c_id,votes| votes == leader_votes }
return [tied.map { |c_id,votes| c_id }, spoiled]
end

if loser_votes == leader_votes
# There must be either a tie or a degenerate election
if candidates.size == 1 # Only one candidate, must be the winner
return [leader_id, spoiled]
else
# TODO: add tie-breaking code here
return [candidates.select { |c_id,votes|
votes == leader_votes and c_id != 0 }.map { |c_id,votes| c_id }, spoiled]
resolve_tie.call
end
end

if leader_votes > total/2.0
# max only returns one candidate, so check if two have the same amount of votes
if candidates.select { |c_id,votes| votes == leader_votes }.size > 1
if real_candidates.values.select { |votes| votes == leader_votes }.size > 1
# Tie; return the tied candidates
# TODO: Add tie-breaking code here
return [candidates.select { |c_id,votes| votes == leader_votes }.map { |c_id,votes| c_id }, spoiled]
resolve_tie.call
else
return [leader_id, spoiled]
end
Expand Down

0 comments on commit 3df4924

Please sign in to comment.