use crate::interface::{WithSeats, WithVotes};
pub fn loosemore_hanby_index<C: WithSeats + WithVotes>(candidacies: &[C]) -> f32 {
let total_votes: f32 = candidacies.iter().map(|c| c.get_votes() as f32).sum();
let total_seats: f32 = candidacies.iter().map(|c| c.get_seats() as f32).sum();
let v = candidacies
.iter()
.map(|c| c.get_votes() as f32 / total_votes);
let s = candidacies
.iter()
.map(|c| c.get_seats() as f32 / total_seats);
v.zip(s).map(|(v_i, s_i)| (v_i - s_i).abs()).sum::<f32>() / 2f32
}
pub fn rose_index<C: WithSeats + WithVotes>(candidacies: &[C]) -> f32 {
1f32 - loosemore_hanby_index(candidacies)
}
pub fn sainte_lague_index<C: WithSeats + WithVotes>(candidacies: &[C]) -> f32 {
let total_votes: f32 = candidacies.iter().map(|c| c.get_votes() as f32).sum();
let total_seats: f32 = candidacies.iter().map(|c| c.get_seats() as f32).sum();
let v = candidacies
.iter()
.map(|c| c.get_votes() as f32 / total_votes);
let s = candidacies
.iter()
.map(|c| c.get_seats() as f32 / total_seats);
v.zip(s)
.map(|(v_i, s_i)| (s_i - v_i).powi(2) / v_i)
.sum::<f32>()
/ 2f32
}
pub fn gallagher_index<C: WithSeats + WithVotes>(candidacies: &[C]) -> f32 {
let total_votes: f32 = candidacies.iter().map(|c| c.get_votes() as f32).sum();
let total_seats: f32 = candidacies.iter().map(|c| c.get_seats() as f32).sum();
let v = candidacies
.iter()
.map(|c| c.get_votes() as f32 / total_votes);
let s = candidacies
.iter()
.map(|c| c.get_seats() as f32 / total_seats);
(v.zip(s).map(|(v_i, s_i)| (s_i - v_i).powi(2)).sum::<f32>() / 2f32).sqrt()
}