65 lines
1.3 KiB
Rust
65 lines
1.3 KiB
Rust
use crate::{ballot::{Ballot, BallotType}, header::Header};
|
|
|
|
|
|
#[derive(Debug)]
|
|
pub struct Counter {
|
|
pub header: Header,
|
|
pub ballots: Vec<Ballot>,
|
|
}
|
|
|
|
impl Counter {
|
|
pub fn new<T: std::io::BufRead>(mut csv: quick_csv::Csv<T>) -> Result<Self, Box<dyn std::error::Error>> {
|
|
let header = Header::parse(csv.next().ok_or("csv header missing")??)?;
|
|
let mut ballots = Vec::new();
|
|
|
|
for row in csv {
|
|
ballots.push(Ballot::parse(row?, &header)?.to_candidate_ballot(&header));
|
|
}
|
|
|
|
Ok(Counter {
|
|
header,
|
|
ballots,
|
|
})
|
|
}
|
|
|
|
pub fn count_primaries<T>(&self, ty: BallotType, running: &[bool]) -> Vec<T> where T: num::Num + Copy + std::ops::AddAssign {
|
|
let mut scores = vec![T::zero(); running.len()];
|
|
|
|
for ballot in self.ballots.iter() {
|
|
if ballot.ty != ty {
|
|
continue;
|
|
}
|
|
for &id in ballot.votes.iter() {
|
|
if !running[id] {
|
|
continue;
|
|
}
|
|
scores[id] += T::one();
|
|
break;
|
|
}
|
|
}
|
|
|
|
scores
|
|
}
|
|
|
|
pub fn count_all_with_powers_of_2(&self, ty: BallotType, running: &[bool]) -> Vec<f64> {
|
|
let mut scores = vec![0.0; running.len()];
|
|
|
|
for ballot in self.ballots.iter() {
|
|
if ballot.ty != ty {
|
|
continue;
|
|
}
|
|
let mut m = 0.5;
|
|
for &id in ballot.votes.iter() {
|
|
if !running[id] {
|
|
continue;
|
|
}
|
|
scores[id] += m;
|
|
m *= 0.5;
|
|
}
|
|
}
|
|
|
|
scores
|
|
}
|
|
}
|
|
|