add tests and handle ties
This commit is contained in:
+52
-6
@@ -4,6 +4,12 @@ const VOTE_SEPARATOR: &str = "- Vote Separator -\n";
|
||||
const ANIME_SEPARATOR: &str = " | ";
|
||||
const VALUE_SEPARATOR: &str = ",";
|
||||
|
||||
#[derive(PartialEq)]
|
||||
enum ElectionResult {
|
||||
Winner((usize, usize), usize),
|
||||
Tie,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = std::env::args().skip(1).collect();
|
||||
if args.len() != 1 {
|
||||
@@ -48,6 +54,14 @@ fn select_winners(
|
||||
let mut r: Vec<((usize, usize), usize)> = Combinations::of_size(0..candidate_count, 2)
|
||||
.map(|v| (v[0], v[1]))
|
||||
.map(|c| single_election(c, votes))
|
||||
// Remove ties
|
||||
.filter_map(|m| {
|
||||
if let ElectionResult::Winner(relation, margin) = m {
|
||||
Some((relation, margin))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
r.sort_by_key(|e| e.1);
|
||||
let mut result = Vec::new();
|
||||
@@ -60,7 +74,7 @@ fn select_winners(
|
||||
for _ in 0..amount_of_winners {
|
||||
let winner = (0..candidate_count)
|
||||
// Find new winners each time.
|
||||
.filter(|c| !winners.contains(&c))
|
||||
.filter(|c| !winners.contains(c))
|
||||
.map(|c| {
|
||||
(
|
||||
c,
|
||||
@@ -85,7 +99,7 @@ fn select_winners(
|
||||
fn single_election(
|
||||
(candidate_a, candidate_b): (usize, usize),
|
||||
votes: &[Vec<usize>],
|
||||
) -> ((usize, usize), usize) {
|
||||
) -> ElectionResult {
|
||||
let (mut a_votes, mut b_votes): (usize, usize) = (0, 0);
|
||||
for vote in votes {
|
||||
if vote[candidate_a] == vote[candidate_b] {
|
||||
@@ -98,15 +112,17 @@ fn single_election(
|
||||
}
|
||||
}
|
||||
if a_votes > b_votes {
|
||||
(
|
||||
ElectionResult::Winner(
|
||||
(candidate_a, candidate_b),
|
||||
a_votes.max(b_votes) - a_votes.min(b_votes),
|
||||
)
|
||||
} else {
|
||||
(
|
||||
} else if a_votes < b_votes {
|
||||
ElectionResult::Winner(
|
||||
(candidate_b, candidate_a),
|
||||
a_votes.max(b_votes) - a_votes.min(b_votes),
|
||||
)
|
||||
} else {
|
||||
ElectionResult::Tie
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,11 +141,41 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn connection_test() {
|
||||
fn connection() {
|
||||
let graph = [(0, 1), (1, 2), (0, 2), (2, 3)];
|
||||
assert!(connection_exists(&graph, (0, 3)));
|
||||
assert!(!connection_exists(&graph, (3, 0)));
|
||||
let graph = [(0, 1)];
|
||||
assert!(!connection_exists(&graph, (3, 0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn votes() {
|
||||
let candidates = ["Alice", "Bob", "Carol", "Dave"];
|
||||
let votes: Vec<Vec<usize>> = vec![
|
||||
vec![5, 4, 1, 0],
|
||||
vec![5, 3, 2, 0],
|
||||
vec![4, 5, 1, 0],
|
||||
vec![5, 4, 0, 1],
|
||||
vec![4, 3, 2, 0],
|
||||
vec![5, 2, 1, 0],
|
||||
vec![3, 5, 2, 0],
|
||||
];
|
||||
let winners = select_winners(&votes, candidates.len(), candidates.len());
|
||||
assert!(winners[0] == 0);
|
||||
assert!(winners[3] == 3);
|
||||
|
||||
let candidates = ["Alice", "Bob", "Carol"];
|
||||
let votes: Vec<Vec<usize>> = vec![
|
||||
vec![5, 3, 1],
|
||||
vec![5, 3, 1],
|
||||
vec![3, 5, 1],
|
||||
vec![3, 5, 1],
|
||||
vec![1, 3, 5],
|
||||
vec![1, 3, 5],
|
||||
vec![5, 1, 3],
|
||||
];
|
||||
let winners = select_winners(&votes, candidates.len(), candidates.len());
|
||||
assert!(winners[0] == 1);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user