add tests and handle ties

This commit is contained in:
2026-05-07 18:17:43 +02:00
parent a2c47ce692
commit 32d0332eba
+52 -6
View File
@@ -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);
}
}