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 {
type Output = Rational;
fn add(self, _rhs: &Rational) -> Self::Output {
todo!()
}
fn add(self, rhs: &Rational) -> Self::Output { Rational(self.0 + &rhs.0) }
}
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>) {
let mut votes = Vec::new();
for ballot in state.election.ballots.iter() {
let vote = Vote {
ballot: ballot,
value: ballot.orig_value.clone(),
up_to_pref: 0,
};
votes.push(vote);
}
let votes = state.election.ballots.iter().map(|b| Vote {
ballot: b,
value: b.orig_value.clone(),
up_to_pref: 0,
}).collect();
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>) {
// Calculate the total vote
state.quota = N::zero();
for count_card in state.candidates.values() {
state.quota += &count_card.votes;
}
state.quota = state.candidates.values().fold(N::zero(), |acc, cc| { acc + &cc.votes });
// TODO: Different quotas
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>) {
// Can't use filter(...) magic because of conflict with borrow checker
let mut cands_meeting_quota = Vec::new();
for (candidate, count_card) in state.candidates.iter_mut() {
if count_card.state == CandidateState::HOPEFUL && meets_quota(&state.quota, count_card) {
cands_meeting_quota.push((candidate, count_card));
}
}
let quota = &state.quota; // Have to do this or else the borrow checker gets confused
let mut cands_meeting_quota: Vec<(&&Candidate, &mut CountCard<N>)> = state.candidates.iter_mut()
.filter(|(_, cc)| cc.state == CandidateState::HOPEFUL && meets_quota(quota, cc))
.collect();
if cands_meeting_quota.len() > 0 {
// 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> {
// As above regarding filter(...)
let mut has_surplus = Vec::new();
for (candidate, count_card) in state.candidates.iter() {
if count_card.votes > state.quota {
has_surplus.push((candidate, count_card));
}
}
let mut has_surplus: Vec<(&&Candidate, &CountCard<N>)> = state.candidates.iter()
.filter(|(_, cc)| cc.votes > state.quota)
.collect();
if has_surplus.len() > 0 {
// 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 {
if state.election.candidates.len() - state.num_excluded <= state.election.seats {
// Bulk elect all remaining candidates
let mut hopefuls = Vec::new();
for (candidate, count_card) in state.candidates.iter_mut() {
if count_card.state == CandidateState::HOPEFUL {
hopefuls.push((candidate, count_card));
}
}
let mut hopefuls: Vec<(&&Candidate, &mut CountCard<N>)> = state.candidates.iter_mut()
.filter(|(_, cc)| cc.state == CandidateState::HOPEFUL)
.collect();
// TODO: Handle ties
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 {
let mut hopefuls = Vec::new();
for (candidate, count_card) in state.candidates.iter() {
if count_card.state == CandidateState::HOPEFUL {
hopefuls.push((candidate, count_card));
}
}
let mut hopefuls: Vec<(&&Candidate, &CountCard<N>)> = state.candidates.iter()
.filter(|(_, cc)| cc.state == CandidateState::HOPEFUL)
.collect();
// Sort by votes
// 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 {
let mut excluded_with_votes = Vec::new();
for (candidate, count_card) in state.candidates.iter() {
if count_card.state == CandidateState::EXCLUDED && !count_card.votes.is_zero() {
excluded_with_votes.push((candidate, count_card));
}
}
let mut excluded_with_votes: Vec<(&&Candidate, &CountCard<N>)> = state.candidates.iter()
.filter(|(_, cc)| cc.state == CandidateState::EXCLUDED && !cc.votes.is_zero())
.collect();
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());