Tournament

1. Readme

锦标赛

统计一场小型足球比赛的结果.

基于一个输入文件,它包含哪个队与哪个队进行比赛,结果是什么。用下面的表格创建出一个文件:

Team                           | MP |  W |  D |  L |  P
Devastating Donkeys            |  3 |  2 |  1 |  0 |  7
Allegoric Alaskans             |  3 |  2 |  0 |  1 |  6
Blithering Badgers             |  3 |  1 |  0 |  2 |  3
Courageous Californians        |  3 |  0 |  1 |  2 |  1

那些缩写是什么意思?

  • MP:赛次
  • W:比赛赢了
  • D:打平
  • L:比赛输了
  • P:分

一场胜利,3 分。打平 1 分。输了 0 分.

结果应该按分数下降排序。在平局的情况下,球队按字母顺序排列。

输入

你的梳理程序,将接收像这样的输入:

Allegoric Alaskans;Blithering Badgers;win
Devastating Donkeys;Courageous Californians;draw
Devastating Donkeys;Allegoric Alaskans;win
Courageous Californians;Blithering Badgers;loss
Blithering Badgers;Devastating Donkeys;loss
Allegoric Alaskans;Courageous Californians;win

一行中首个队伍名是主队。所以这一行

Allegoric Alaskans;Blithering Badgers;win

意味着,Allegoric Alaskans 打败了 Blithering Badgers。

这行:

Courageous Californians;Blithering Badgers;loss

意味着,Courageous Californians 输给了 Blithering Badgers

这行:

Devastating Donkeys;Courageous Californians;draw

意味着,Devastating Donkeys 与 Courageous Californians 打平

2. 开始你的表演

pub fn tally(match_results: &str) -> String {
   unimplemented!(
       "Given the result of the played matches '{}' return a properly formatted tally table string.",
       match_results
   );
}

3. 测试代码查看


# #![allow(unused_variables)]
#fn main() {
#[test]
fn just_the_header_if_no_input() {
   let input = "";
   let expected = "Team                           | MP |  W |  D |  L |  P";

   assert_eq!(tally(&input), expected);
}

#[test]
//#[ignore]
fn a_win_is_three_points_a_loss_is_zero_points() {
   let input = "Allegoric Alaskans;Blithering Badgers;win";
   let expected = "Team                           | MP |  W |  D |  L |  P\n".to_string()
       + "Allegoric Alaskans             |  1 |  1 |  0 |  0 |  3\n"
       + "Blithering Badgers             |  1 |  0 |  0 |  1 |  0";

   assert_eq!(tally(&input), expected);
}

#[test]
//#[ignore]
fn a_win_can_also_be_expressed_as_a_loss() {
   let input = "Blithering Badgers;Allegoric Alaskans;loss";
   let expected = "Team                           | MP |  W |  D |  L |  P\n".to_string()
       + "Allegoric Alaskans             |  1 |  1 |  0 |  0 |  3\n"
       + "Blithering Badgers             |  1 |  0 |  0 |  1 |  0";

   assert_eq!(tally(&input), expected);
}

#[test]
//#[ignore]
fn a_different_team_can_win() {
   let input = "Blithering Badgers;Allegoric Alaskans;win";
   let expected = "Team                           | MP |  W |  D |  L |  P\n".to_string()
       + "Blithering Badgers             |  1 |  1 |  0 |  0 |  3\n"
       + "Allegoric Alaskans             |  1 |  0 |  0 |  1 |  0";

   assert_eq!(tally(&input), expected);
}

#[test]
//#[ignore]
fn a_draw_is_one_point_each() {
   let input = "Allegoric Alaskans;Blithering Badgers;draw";
   let expected = "Team                           | MP |  W |  D |  L |  P\n".to_string()
       + "Allegoric Alaskans             |  1 |  0 |  1 |  0 |  1\n"
       + "Blithering Badgers             |  1 |  0 |  1 |  0 |  1";

   assert_eq!(tally(&input), expected);
}

#[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";
   let expected = "Team                           | MP |  W |  D |  L |  P\n".to_string()
       + "Allegoric Alaskans             |  2 |  2 |  0 |  0 |  6\n"
       + "Blithering Badgers             |  2 |  0 |  0 |  2 |  0";

   assert_eq!(tally(&input), expected);
}

#[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";
   let expected = "Team                           | MP |  W |  D |  L |  P\n".to_string()
       + "Allegoric Alaskans             |  2 |  1 |  0 |  1 |  3\n"
       + "Blithering Badgers             |  2 |  1 |  0 |  1 |  3";

   assert_eq!(tally(&input), expected);
}

#[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"
       + "Courageous Californians;Allegoric Alaskans;loss";
   let expected = "Team                           | MP |  W |  D |  L |  P\n".to_string()
       + "Allegoric Alaskans             |  2 |  2 |  0 |  0 |  6\n"
       + "Blithering Badgers             |  2 |  1 |  0 |  1 |  3\n"
       + "Courageous Californians        |  2 |  0 |  0 |  2 |  0";

   assert_eq!(tally(&input), expected);
}

#[test]
//#[ignore]
fn typical_input() {
   let input = "Allegoric Alaskans;Blithering Badgers;win\n".to_string()
       + "Devastating Donkeys;Courageous Californians;draw\n"
       + "Devastating Donkeys;Allegoric Alaskans;win\n"
       + "Courageous Californians;Blithering Badgers;loss\n"
       + "Blithering Badgers;Devastating Donkeys;loss\n"
       + "Allegoric Alaskans;Courageous Californians;win";
   let expected = "Team                           | MP |  W |  D |  L |  P\n".to_string()
       + "Devastating Donkeys            |  3 |  2 |  1 |  0 |  7\n"
       + "Allegoric Alaskans             |  3 |  2 |  0 |  1 |  6\n"
       + "Blithering Badgers             |  3 |  1 |  0 |  2 |  3\n"
       + "Courageous Californians        |  3 |  0 |  1 |  2 |  1";

   assert_eq!(tally(&input), expected);
}

#[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"
       + "Courageous Californians;Blithering Badgers;draw\n"
       + "Allegoric Alaskans;Courageous Californians;win";
   let expected = "Team                           | MP |  W |  D |  L |  P\n".to_string()
       + "Allegoric Alaskans             |  3 |  2 |  0 |  1 |  6\n"
       + "Blithering Badgers             |  2 |  1 |  1 |  0 |  4\n"
       + "Courageous Californians        |  2 |  0 |  1 |  1 |  1\n"
       + "Devastating Donkeys            |  1 |  0 |  0 |  1 |  0";

   assert_eq!(tally(&input), expected);
}

#[test]
//#[ignore]
fn ties_broken_alphabetically() {
   let input = "Courageous Californians;Devastating Donkeys;win\n".to_string()
       + "Allegoric Alaskans;Blithering Badgers;win\n"
       + "Devastating Donkeys;Allegoric Alaskans;loss\n"
       + "Courageous Californians;Blithering Badgers;win\n"
       + "Blithering Badgers;Devastating Donkeys;draw\n"
       + "Allegoric Alaskans;Courageous Californians;draw";
   let expected = "Team                           | MP |  W |  D |  L |  P\n".to_string()
       + "Allegoric Alaskans             |  3 |  2 |  1 |  0 |  7\n"
       + "Courageous Californians        |  3 |  2 |  1 |  0 |  7\n"
       + "Blithering Badgers             |  3 |  0 |  1 |  2 |  1\n"
       + "Devastating Donkeys            |  3 |  0 |  1 |  2 |  1";

   assert_eq!(tally(&input), expected);
}

#}

4. 答案


# #![allow(unused_variables)]
#fn main() {
use std::cmp::Ordering::Equal;
use std::collections::HashMap;

enum GameResult {
   Win,
   Draw,
   Loss,
}

struct TeamResult {
   wins: u32,
   draws: u32,
   losses: u32,
}

impl TeamResult {
   fn new() -> TeamResult {
       TeamResult {
           wins: 0,
           draws: 0,
           losses: 0,
       }
   }
   fn add_game_result(&mut self, result: GameResult) {
       match result {
           GameResult::Win => self.wins += 1,
           GameResult::Draw => self.draws += 1,
           GameResult::Loss => self.losses += 1,
       }
   }
}

pub fn tally(input: &str) -> String {
   let mut results: HashMap<String, TeamResult> = HashMap::new();
   for line in input.to_string().lines() {
       let parts: Vec<&str> = line.trim_right().split(';').collect();
       if parts.len() != 3 {
           continue;
       }
       let team1 = parts[0];
       let team2 = parts[1];
       let outcome = parts[2];
       match outcome {
           "win" => {
               add_game_result(&mut results, team1.to_string(), GameResult::Win);
               add_game_result(&mut results, team2.to_string(), GameResult::Loss);
           }
           "draw" => {
               add_game_result(&mut results, team1.to_string(), GameResult::Draw);
               add_game_result(&mut results, team2.to_string(), GameResult::Draw);
           }
           "loss" => {
               add_game_result(&mut results, team1.to_string(), GameResult::Loss);
               add_game_result(&mut results, team2.to_string(), GameResult::Win);
           }
           _ => (), // Ignore bad lines
       }
   }
   write_tally(&results)
}

fn write_tally(results: &HashMap<String, TeamResult>) -> String {
   let mut v: Vec<_> = results
       .iter()
       .map(|(team, r)| {
           let games = r.wins + r.draws + r.losses;
           let points = r.wins * 3 + r.draws;
           (team, games, r, points)
       })
       .collect();
   // Sort by points descending, then name A-Z.
   v.sort_by(|a, b| match a.3.cmp(&(b.3)).reverse() {
       Equal => a.0.cmp(&(b.0)),
       other => other,
   });
   let mut lines = vec![format!("{:30} | MP |  W |  D |  L |  P", "Team")];
   lines.extend(v.iter().map(|&(ref team, games, r, points)| {
       format!(
           "{:30} | {:2} | {:2} | {:2} | {:2} | {:2}",
           team, games, r.wins, r.draws, r.losses, points
       )
   }));
   lines.join("\n")
}

fn add_game_result(results: &mut HashMap<String, TeamResult>, team: String, result: GameResult) {
   results
       .entry(team)
       .or_insert(TeamResult::new())
       .add_game_result(result);
}

#}



填充/相关