Some refactoring

This commit is contained in:
RunasSudo 2021-05-28 22:37:18 +10:00
parent 5731d71b07
commit e6d57685cb
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
2 changed files with 24 additions and 48 deletions

View File

@ -158,9 +158,7 @@ impl ops::Rem for Rational {
impl ops::Add<&Rational> for Rational { impl ops::Add<&Rational> for Rational {
type Output = Rational; type Output = Rational;
fn add(self, _rhs: &Rational) -> Self::Output { fn add(self, rhs: &Rational) -> Self::Output { Rational(self.0 + &rhs.0) }
todo!()
}
} }
impl ops::Sub<&Rational> for Rational { impl ops::Sub<&Rational> for Rational {

View File

@ -89,15 +89,11 @@ fn next_preferences<'a, N: Number>(state: &CountState<'a, N>, votes: Vec<Vote<'a
} }
pub fn distribute_first_preferences<N: Number>(state: &mut CountState<N>) { pub fn distribute_first_preferences<N: Number>(state: &mut CountState<N>) {
let mut votes = Vec::new(); let votes = state.election.ballots.iter().map(|b| Vote {
for ballot in state.election.ballots.iter() { ballot: b,
let vote = Vote { value: b.orig_value.clone(),
ballot: ballot, up_to_pref: 0,
value: ballot.orig_value.clone(), }).collect();
up_to_pref: 0,
};
votes.push(vote);
}
let result = next_preferences(state, votes); let result = next_preferences(state, votes);
@ -117,10 +113,7 @@ pub fn distribute_first_preferences<N: Number>(state: &mut CountState<N>) {
pub fn calculate_quota<N: Number>(state: &mut CountState<N>) { pub fn calculate_quota<N: Number>(state: &mut CountState<N>) {
// Calculate the total vote // Calculate the total vote
state.quota = N::zero(); state.quota = state.candidates.values().fold(N::zero(), |acc, cc| { acc + &cc.votes });
for count_card in state.candidates.values() {
state.quota += &count_card.votes;
}
// TODO: Different quotas // TODO: Different quotas
state.quota /= N::from(state.election.seats + 1); state.quota /= N::from(state.election.seats + 1);
@ -136,13 +129,10 @@ fn meets_quota<N: Number>(quota: &N, count_card: &CountCard<N>) -> bool {
} }
pub fn elect_meeting_quota<N: Number>(state: &mut CountState<N>) { pub fn elect_meeting_quota<N: Number>(state: &mut CountState<N>) {
// Can't use filter(...) magic because of conflict with borrow checker let quota = &state.quota; // Have to do this or else the borrow checker gets confused
let mut cands_meeting_quota = Vec::new(); let mut cands_meeting_quota: Vec<(&&Candidate, &mut CountCard<N>)> = state.candidates.iter_mut()
for (candidate, count_card) in state.candidates.iter_mut() { .filter(|(_, cc)| cc.state == CandidateState::HOPEFUL && meets_quota(quota, cc))
if count_card.state == CandidateState::HOPEFUL && meets_quota(&state.quota, count_card) { .collect();
cands_meeting_quota.push((candidate, count_card));
}
}
if cands_meeting_quota.len() > 0 { if cands_meeting_quota.len() > 0 {
// Sort by votes // Sort by votes
@ -159,13 +149,9 @@ pub fn elect_meeting_quota<N: Number>(state: &mut CountState<N>) {
} }
pub fn distribute_surpluses<N: Number>(state: &mut CountState<N>) -> bool where for<'r> &'r N: Sub<&'r N, Output=N> { pub fn distribute_surpluses<N: Number>(state: &mut CountState<N>) -> bool where for<'r> &'r N: Sub<&'r N, Output=N> {
// As above regarding filter(...) let mut has_surplus: Vec<(&&Candidate, &CountCard<N>)> = state.candidates.iter()
let mut has_surplus = Vec::new(); .filter(|(_, cc)| cc.votes > state.quota)
for (candidate, count_card) in state.candidates.iter() { .collect();
if count_card.votes > state.quota {
has_surplus.push((candidate, count_card));
}
}
if has_surplus.len() > 0 { if has_surplus.len() > 0 {
// TODO: Different sorting orders // TODO: Different sorting orders
@ -229,12 +215,10 @@ fn distribute_surplus<N: Number>(state: &mut CountState<N>, elected_candidate: &
pub fn bulk_elect<N: Number>(state: &mut CountState<N>) -> bool { pub fn bulk_elect<N: Number>(state: &mut CountState<N>) -> bool {
if state.election.candidates.len() - state.num_excluded <= state.election.seats { if state.election.candidates.len() - state.num_excluded <= state.election.seats {
// Bulk elect all remaining candidates // Bulk elect all remaining candidates
let mut hopefuls = Vec::new(); let mut hopefuls: Vec<(&&Candidate, &mut CountCard<N>)> = state.candidates.iter_mut()
for (candidate, count_card) in state.candidates.iter_mut() { .filter(|(_, cc)| cc.state == CandidateState::HOPEFUL)
if count_card.state == CandidateState::HOPEFUL { .collect();
hopefuls.push((candidate, count_card));
}
}
// TODO: Handle ties // TODO: Handle ties
hopefuls.sort_unstable_by(|a, b| a.1.votes.partial_cmp(&b.1.votes).unwrap()); hopefuls.sort_unstable_by(|a, b| a.1.votes.partial_cmp(&b.1.votes).unwrap());
@ -250,12 +234,9 @@ pub fn bulk_elect<N: Number>(state: &mut CountState<N>) -> bool {
} }
pub fn exclude_hopefuls<N: Number>(state: &mut CountState<N>) -> bool { pub fn exclude_hopefuls<N: Number>(state: &mut CountState<N>) -> bool {
let mut hopefuls = Vec::new(); let mut hopefuls: Vec<(&&Candidate, &CountCard<N>)> = state.candidates.iter()
for (candidate, count_card) in state.candidates.iter() { .filter(|(_, cc)| cc.state == CandidateState::HOPEFUL)
if count_card.state == CandidateState::HOPEFUL { .collect();
hopefuls.push((candidate, count_card));
}
}
// Sort by votes // Sort by votes
// TODO: Handle ties // TODO: Handle ties
@ -269,12 +250,9 @@ pub fn exclude_hopefuls<N: Number>(state: &mut CountState<N>) -> bool {
} }
pub fn continue_exclusion<N: Number>(state: &mut CountState<N>) -> bool { pub fn continue_exclusion<N: Number>(state: &mut CountState<N>) -> bool {
let mut excluded_with_votes = Vec::new(); let mut excluded_with_votes: Vec<(&&Candidate, &CountCard<N>)> = state.candidates.iter()
for (candidate, count_card) in state.candidates.iter() { .filter(|(_, cc)| cc.state == CandidateState::EXCLUDED && !cc.votes.is_zero())
if count_card.state == CandidateState::EXCLUDED && !count_card.votes.is_zero() { .collect();
excluded_with_votes.push((candidate, count_card));
}
}
if excluded_with_votes.len() > 0 { if excluded_with_votes.len() > 0 {
excluded_with_votes.sort_unstable_by(|a, b| a.1.order_elected.partial_cmp(&b.1.order_elected).unwrap()); excluded_with_votes.sort_unstable_by(|a, b| a.1.order_elected.partial_cmp(&b.1.order_elected).unwrap());