From a4a28f33450abb5f79894cbe7d57564c81960443 Mon Sep 17 00:00:00 2001 From: RunasSudo Date: Tue, 1 Jun 2021 18:57:56 +1000 Subject: [PATCH] Implement --surplus-order --- src/main.rs | 8 ++++++++ src/stv/mod.rs | 18 ++++++++++++++++-- tests/aec.rs | 1 + 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index fa166cc..ed56d8b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -72,6 +72,9 @@ struct STV { #[clap(help_heading=Some("STV VARIANTS"), long, possible_values=&["wig", "uig", "eg", "meek"], default_value="wig", value_name="method")] surplus: String, + #[clap(help_heading=Some("STV VARIANTS"), long, possible_values=&["by_size", "by_order"], default_value="by_size", value_name="order")] + surplus_order: String, + /// Examine only transferable papers during surplus distributions #[clap(help_heading=Some("STV VARIANTS"), long)] transferable_only: bool, @@ -131,6 +134,11 @@ where "meek" => stv::SurplusMethod::Meek, _ => panic!("Invalid --surplus"), }, + surplus_order: match cmd_opts.surplus_order.as_str() { + "by_size" => stv::SurplusOrder::BySize, + "by_order" => stv::SurplusOrder::ByOrder, + _ => panic!("Invalid --surplus-order"), + }, transferable_only: cmd_opts.transferable_only, exclusion: match cmd_opts.exclusion.as_str() { "single_stage" => stv::ExclusionMethod::SingleStage, diff --git a/src/stv/mod.rs b/src/stv/mod.rs index 148d241..da6a454 100644 --- a/src/stv/mod.rs +++ b/src/stv/mod.rs @@ -32,6 +32,7 @@ use std::ops; pub struct STVOptions { pub round_votes: Option, pub surplus: SurplusMethod, + pub surplus_order: SurplusOrder, pub transferable_only: bool, pub exclusion: ExclusionMethod, pub pp_decimals: usize, @@ -46,6 +47,13 @@ pub enum SurplusMethod { Meek, } +#[wasm_bindgen] +#[derive(Clone, Copy)] +pub enum SurplusOrder { + BySize, + ByOrder, +} + #[wasm_bindgen] #[derive(Clone, Copy)] pub enum ExclusionMethod { @@ -253,8 +261,14 @@ where .collect(); if has_surplus.len() > 0 { - // TODO: Different sorting orders - has_surplus.sort_unstable_by(|a, b| a.1.order_elected.partial_cmp(&b.1.order_elected).unwrap()); + match opts.surplus_order { + SurplusOrder::BySize => { + has_surplus.sort_unstable_by(|a, b| a.1.votes.partial_cmp(&b.1.votes).unwrap()); + } + SurplusOrder::ByOrder => { + has_surplus.sort_unstable_by(|a, b| a.1.order_elected.partial_cmp(&b.1.order_elected).unwrap()); + } + } // Distribute top candidate's surplus // TODO: Handle ties diff --git a/tests/aec.rs b/tests/aec.rs index 9972d59..d7a8bc5 100644 --- a/tests/aec.rs +++ b/tests/aec.rs @@ -56,6 +56,7 @@ fn aec_tas19_rational() { let stv_opts = stv::STVOptions { round_votes: Some(0), surplus: stv::SurplusMethod::UIG, + surplus_order: stv::SurplusOrder::ByOrder, transferable_only: false, exclusion: stv::ExclusionMethod::ByValue, pp_decimals: 2,