///|
/// First-choice weighted counts in candidate order.
pub fn Election::plurality(self : Election) -> Array[(String, Int)] {
let scores = Array::make(self.candidates.length(), 0)
for ballot in self.ballots {
if ballot.ranking.length() > 0 {
let id = ballot.ranking[0]
for i, candidate in self.candidates {
if candidate == id {
scores[i] += ballot.weight
}
}
}
}
let out = []
for i, candidate in self.candidates {
out.push((candidate, scores[i]))
}
out
}
///|
/// Candidates tied for the maximum plurality score.
pub fn Election::plurality_winners(self : Election) -> Array[String] {
let rows = self.plurality()
let mut best = -1
for row in rows {
if row.1 > best {
best = row.1
}
}
let out = []
for row in rows {
if row.1 == best {
out.push(row.0)
}
}
out
}
///|
/// Fixed-N Borda score. Unranked candidates tie at zero.
pub fn Election::borda(self : Election) -> Array[(String, Int)] {
let scores = Array::make(self.candidates.length(), 0)
let n = self.candidates.length()
for ballot in self.ballots {
let ranks = ballot.ranking.length()
for pos, id in ballot.ranking {
for i, candidate in self.candidates {
if candidate == id {
scores[i] += ballot.weight * (n - pos - 1)
}
}
}
if ranks == 0 {
()
}
}
let out = []
for i, candidate in self.candidates {
out.push((candidate, scores[i]))
}
out
}
///|
/// Candidates tied for the maximum Borda score.
pub fn Election::borda_winners(self : Election) -> Array[String] {
let rows = self.borda()
let mut best = -1
for row in rows {
if row.1 > best {
best = row.1
}
}
let out = []
for row in rows {
if row.1 == best {
out.push(row.0)
}
}
out
}