From 7c69c33b99c58b7077a81561a9bae23ac8675ebb Mon Sep 17 00:00:00 2001 From: Julio Biason Date: Tue, 30 Jun 2020 21:44:37 -0300 Subject: [PATCH] Solution --- rust/tournament/src/lib.rs | 112 +++++++++++++++++++++++++++- rust/tournament/tests/tournament.rs | 10 --- 2 files changed, 108 insertions(+), 14 deletions(-) diff --git a/rust/tournament/src/lib.rs b/rust/tournament/src/lib.rs index 880dabd..ca03ced 100644 --- a/rust/tournament/src/lib.rs +++ b/rust/tournament/src/lib.rs @@ -1,6 +1,110 @@ +use std::collections::HashMap; + +const HEADER: &str = "Team | MP | W | D | L | P"; + +#[derive(Default, Eq, PartialEq)] +struct Team { + name: String, + matches: u8, + wins: u8, + draws: u8, + losses: u8, + points: u16, +} + +impl Team { + fn new(name: String) -> Self { + Self { + name, + ..Default::default() + } + } + + fn win(&mut self) { + self.wins += 1; + self.matches += 1; + self.points += 3; + } + + fn lose(&mut self) { + self.losses += 1; + self.matches += 1; + } + + fn draw(&mut self) { + self.draws += 1; + self.matches += 1; + self.points += 1; + } + + fn add_match(&mut self, result: &MatchResult) { + match result { + MatchResult::Win => self.win(), + MatchResult::Loss => self.lose(), + MatchResult::Draw => self.draw(), + } + } +} + +impl From<&Team> for String { + fn from(origin: &Team) -> String { + format!( + "{:<30} | {:>2} | {:>2} | {:>2} | {:>2} | {:>2}", + origin.name, origin.matches, origin.wins, origin.draws, origin.losses, origin.points + ) + } +} + +enum MatchResult { + Win, + Loss, + Draw, +} + +impl From<&str> for MatchResult { + fn from(origin: &str) -> MatchResult { + match origin { + "win" => MatchResult::Win, + "loss" => MatchResult::Loss, + "draw" => MatchResult::Draw, + _ => panic!(), + } + } +} + +impl MatchResult { + fn reverse(&self) -> Self { + match self { + MatchResult::Win => MatchResult::Loss, + MatchResult::Loss => MatchResult::Win, + MatchResult::Draw => MatchResult::Draw, + } + } +} + pub fn tally(match_results: &str) -> String { - unimplemented!( - "Given the result of the played matches '{}' return a properly formatted tally table string.", - match_results - ); + let mut scores: HashMap = HashMap::new(); + match_results.lines().for_each(|line| { + let frags: Vec<&str> = line.split(";").collect(); + let home = frags[0]; + let away = frags[1]; + let result = frags[2].into(); + scores + .entry(home.into()) + .or_insert(Team::new(home.into())) + .add_match(&result); + scores + .entry(away.into()) + .or_insert(Team::new(away.into())) + .add_match(&result.reverse()); + }); + + let mut score_values: Vec<&Team> = scores.values().collect(); + score_values.sort_by(|a, b| b.points.cmp(&a.points).then_with(|| a.name.cmp(&b.name))); + + vec![String::from(HEADER)] + .into_iter() + .chain(score_values.into_iter().map(|t| t.into())) + .collect::>() + .join("\n") } diff --git a/rust/tournament/tests/tournament.rs b/rust/tournament/tests/tournament.rs index 57be243..bcb0664 100644 --- a/rust/tournament/tests/tournament.rs +++ b/rust/tournament/tests/tournament.rs @@ -9,7 +9,6 @@ fn just_the_header_if_no_input() { } #[test] -#[ignore] fn a_win_is_three_points_a_loss_is_zero_points() { let input = "Allegoric Alaskans;Blithering Badgers;win"; let expected = "".to_string() @@ -21,7 +20,6 @@ fn a_win_is_three_points_a_loss_is_zero_points() { } #[test] -#[ignore] fn a_win_can_also_be_expressed_as_a_loss() { let input = "Blithering Badgers;Allegoric Alaskans;loss"; let expected = "".to_string() @@ -33,7 +31,6 @@ fn a_win_can_also_be_expressed_as_a_loss() { } #[test] -#[ignore] fn a_different_team_can_win() { let input = "Blithering Badgers;Allegoric Alaskans;win"; let expected = "".to_string() @@ -45,7 +42,6 @@ fn a_different_team_can_win() { } #[test] -#[ignore] fn there_can_be_more_than_one_match() { let input = "Allegoric Alaskans;Blithering Badgers;win\n".to_string() + "Allegoric Alaskans;Blithering Badgers;win"; @@ -58,7 +54,6 @@ fn there_can_be_more_than_one_match() { } #[test] -#[ignore] fn a_draw_is_one_point_each() { let input = "Allegoric Alaskans;Blithering Badgers;draw\n".to_string() + "Allegoric Alaskans;Blithering Badgers;win"; @@ -71,7 +66,6 @@ fn a_draw_is_one_point_each() { } #[test] -#[ignore] fn there_can_be_more_than_one_winner() { let input = "Allegoric Alaskans;Blithering Badgers;loss\n".to_string() + "Allegoric Alaskans;Blithering Badgers;win"; @@ -84,7 +78,6 @@ fn there_can_be_more_than_one_winner() { } #[test] -#[ignore] fn there_can_be_more_than_two_teams() { let input = "Allegoric Alaskans;Blithering Badgers;win\n".to_string() + "Blithering Badgers;Courageous Californians;win\n" @@ -99,7 +92,6 @@ fn there_can_be_more_than_two_teams() { } #[test] -#[ignore] fn typical_input() { let input = "Allegoric Alaskans;Blithering Badgers;win\n".to_string() + "Devastating Donkeys;Courageous Californians;draw\n" @@ -118,7 +110,6 @@ fn typical_input() { } #[test] -#[ignore] fn incomplete_competition_not_all_pairs_have_played() { let input = "Allegoric Alaskans;Blithering Badgers;loss\n".to_string() + "Devastating Donkeys;Allegoric Alaskans;loss\n" @@ -135,7 +126,6 @@ fn incomplete_competition_not_all_pairs_have_played() { } #[test] -#[ignore] fn ties_broken_alphabetically() { let input = "Courageous Californians;Devastating Donkeys;win\n".to_string() + "Allegoric Alaskans;Blithering Badgers;win\n"