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)]
|
#[derive(Debug)]
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
Lose(ScoreItem),
|
Lose(Vec<ScoreItem>),
|
||||||
Win(Vec<ScoreItem>),
|
Win(Vec<ScoreItem>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,26 +61,42 @@ impl Iterator for Counter {
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
let mut winners = Vec::<ScoreItem>::with_capacity(self.enabled.len());
|
let mut winners = Vec::<ScoreItem>::with_capacity(self.enabled.len());
|
||||||
let primaries = self.count_primaries().collect_vec();
|
let mut losers = Vec::<ScoreItem>::with_capacity(self.enabled.len());
|
||||||
let mut lowest = *primaries.first()?;
|
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() {
|
for &score in primaries.iter() {
|
||||||
lowest = lowest.min(score);
|
|
||||||
if score.value >= self.quota {
|
if score.value >= self.quota {
|
||||||
winners.push(score);
|
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 {
|
if primaries.len() == 1 && self.winners_left == 1 {
|
||||||
self.enabled[lowest.index] = false;
|
self.enabled[highest.index] = false;
|
||||||
return Some(Event::Win(vec![lowest]));
|
return Some(Event::Win(vec![highest]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if losers.len() == 0 {
|
||||||
|
losers.push(lowest);
|
||||||
}
|
}
|
||||||
|
|
||||||
if winners.len() == 0 {
|
if winners.len() == 0 {
|
||||||
self.enabled[lowest.index] = false;
|
for score in losers.iter() {
|
||||||
return Some(Event::Lose(lowest));
|
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() {
|
for ballot in self.ballots.iter_mut() {
|
||||||
let index = match ballot.get_primary_index(|id| self.enabled[id]) {
|
let index = match ballot.get_primary_index(|id| self.enabled[id]) {
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
|
|
|
||||||
|
|
@ -36,16 +36,18 @@ fn main() {
|
||||||
|
|
||||||
for (index, event) in (1..).zip(counter) {
|
for (index, event) in (1..).zip(counter) {
|
||||||
match event {
|
match event {
|
||||||
counter::Event::Win(mut v) => {
|
counter::Event::Win(v) => {
|
||||||
eprintln!(" {index}: Win:");
|
eprintln!(" {index}: Win:");
|
||||||
v.sort_by(|a,b| b.cmp(a));
|
|
||||||
for winner in v.iter() {
|
for winner in v.iter() {
|
||||||
eprintln!(" - {}, {}, {}", header.get_candidate_name(winner.index), winner.value, Percent(winner.value, total));
|
eprintln!(" - {}, {}, {}", header.get_candidate_name(winner.index), winner.value, Percent(winner.value, total));
|
||||||
}
|
}
|
||||||
winners.extend_from_slice(&v);
|
winners.extend_from_slice(&v);
|
||||||
}
|
}
|
||||||
counter::Event::Lose(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