mirror of
https://github.com/ArthurDanjou/exercism-rust.git
synced 2026-01-26 18:00:29 +01:00
Initial commit
This commit is contained in:
112
tournament/src/lib.rs
Normal file
112
tournament/src/lib.rs
Normal file
@@ -0,0 +1,112 @@
|
||||
extern crate core;
|
||||
|
||||
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: u8
|
||||
}
|
||||
|
||||
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 draw(&mut self) {
|
||||
self.draws += 1;
|
||||
self.matches += 1;
|
||||
self.points += 1;
|
||||
}
|
||||
|
||||
fn lose(&mut self) {
|
||||
self.losses += 1;
|
||||
self.matches += 1;
|
||||
}
|
||||
|
||||
fn add_match(&mut self, result: &MatchResult) {
|
||||
match result {
|
||||
MatchResult::Win => self.win(),
|
||||
MatchResult::Draw => self.draw(),
|
||||
MatchResult::Loss => self.lose()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Team> for String {
|
||||
fn from(team: &Team) -> String {
|
||||
format!(
|
||||
"{:<30} | {:>2} | {:>2} | {:>2} | {:>2} | {:>2}",
|
||||
team.name, team.matches, team.wins, team.draws, team.losses, team.points
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
enum MatchResult {
|
||||
Win,
|
||||
Draw,
|
||||
Loss
|
||||
}
|
||||
|
||||
impl From<&str> for MatchResult {
|
||||
fn from(result: &str) -> Self {
|
||||
match result {
|
||||
"win" => MatchResult::Win,
|
||||
"draw" => MatchResult::Draw,
|
||||
"loss" => MatchResult::Loss,
|
||||
_ => panic!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MatchResult {
|
||||
fn reverse(&self) -> Self {
|
||||
match self {
|
||||
MatchResult::Win => MatchResult::Loss,
|
||||
MatchResult::Draw => MatchResult::Draw,
|
||||
MatchResult::Loss => MatchResult::Win
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tally(match_results: &str) -> String {
|
||||
let mut scores: HashMap<String, Team> = 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::<Vec<String>>()
|
||||
.join("\n")
|
||||
}
|
||||
Reference in New Issue
Block a user