use std::collections::HashMap;
use crate::core::{Candidate, Id, Method, Ordinal, Profile, SingleWinner};
#[derive(Debug, Clone, serde::Serialize)]
pub struct Borda;
impl Method for Borda {
type Ballot = Ordinal;
type Winner = SingleWinner;
fn outcome(&self, candidates: &[Candidate], profile: Profile<Self::Ballot>) -> Self::Winner {
let mut tally: HashMap<Id, usize> = HashMap::with_capacity(profile.len());
(0..profile.len()).for_each(|i| {
for (i, candidate) in profile[i].iter().enumerate() {
*tally.entry(*candidate).or_insert(0) += profile[i].len() - i;
}
});
let max_count = tally.values().max().unwrap();
let winners: Vec<Id> = tally
.iter()
.filter(|(_, count)| count == &max_count)
.map(|(id, _)| *id)
.collect();
match winners.len() {
0 => SingleWinner::none(),
1 => SingleWinner::win(candidates, winners[0]),
_ => SingleWinner::tie(candidates, &winners),
}
}
}