made it so multiple candidates can lose in 1 round
This commit is contained in:
parent
101db55d04
commit
96f1775004
|
|
@ -4,7 +4,7 @@ use crate::{ballot::Ballot, header::Header, score_item::{ScoreItem, ScoreItems}}
|
|||
|
||||
#[derive(Debug)]
|
||||
pub enum Event {
|
||||
Lose(ScoreItem),
|
||||
Lose(Vec<ScoreItem>),
|
||||
Win(Vec<ScoreItem>),
|
||||
}
|
||||
|
||||
|
|
@ -61,26 +61,42 @@ impl Iterator for Counter {
|
|||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let mut winners = Vec::<ScoreItem>::with_capacity(self.enabled.len());
|
||||
let primaries = self.count_primaries().collect_vec();
|
||||
let mut lowest = *primaries.first()?;
|
||||
let mut losers = Vec::<ScoreItem>::with_capacity(self.enabled.len());
|
||||
let mut primaries = self.count_primaries().collect_vec();
|
||||
primaries.sort_by(|a, b| a.cmp(b));
|
||||
|
||||
let &lowest = primaries.first()?;
|
||||
let &highest = primaries.last()?;
|
||||
let mut lose_total = 0.0;
|
||||
|
||||
for &score in primaries.iter() {
|
||||
lowest = lowest.min(score);
|
||||
if score.value >= self.quota {
|
||||
winners.push(score);
|
||||
}
|
||||
if lose_total + score.value < highest.value {
|
||||
lose_total += score.value;
|
||||
losers.push(score);
|
||||
}
|
||||
}
|
||||
|
||||
if primaries.len() == 1 && self.winners_left == 1 {
|
||||
self.enabled[lowest.index] = false;
|
||||
return Some(Event::Win(vec![lowest]));
|
||||
self.enabled[highest.index] = false;
|
||||
return Some(Event::Win(vec![highest]));
|
||||
}
|
||||
|
||||
if losers.len() == 0 {
|
||||
losers.push(lowest);
|
||||
}
|
||||
|
||||
if winners.len() == 0 {
|
||||
self.enabled[lowest.index] = false;
|
||||
return Some(Event::Lose(lowest));
|
||||
for score in losers.iter() {
|
||||
self.enabled[score.index] = false;
|
||||
}
|
||||
return Some(Event::Lose(losers));
|
||||
}
|
||||
|
||||
winners.sort_by(|a,b| b.cmp(a));
|
||||
|
||||
for ballot in self.ballots.iter_mut() {
|
||||
let index = match ballot.get_primary_index(|id| self.enabled[id]) {
|
||||
Some(v) => v,
|
||||
|
|
|
|||
|
|
@ -36,16 +36,18 @@ fn main() {
|
|||
|
||||
for (index, event) in (1..).zip(counter) {
|
||||
match event {
|
||||
counter::Event::Win(mut v) => {
|
||||
counter::Event::Win(v) => {
|
||||
eprintln!(" {index}: Win:");
|
||||
v.sort_by(|a,b| b.cmp(a));
|
||||
for winner in v.iter() {
|
||||
eprintln!(" - {}, {}, {}", header.get_candidate_name(winner.index), winner.value, Percent(winner.value, total));
|
||||
}
|
||||
winners.extend_from_slice(&v);
|
||||
}
|
||||
counter::Event::Lose(v) => {
|
||||
eprintln!(" {index}: Lose: {}, {}, {}", header.get_candidate_name(v.index), v.value, Percent(v.value, total));
|
||||
eprintln!(" {index}: Lose:");
|
||||
for loser in v.iter() {
|
||||
eprintln!(" - {}, {}, {}", header.get_candidate_name(loser.index), loser.value, Percent(loser.value, total));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue