1
0
Fork 0

Renamed things for clarity and stopped using Ord

This commit is contained in:
Vivianne 2022-12-02 12:03:29 -08:00
parent a5cc701cce
commit b6d2240d51
1 changed files with 44 additions and 62 deletions

View File

@ -1,8 +1,7 @@
use num_derive::FromPrimitive; use num_derive::FromPrimitive;
use num_traits::FromPrimitive; use num_traits::FromPrimitive;
use std::cmp::Ordering;
use std::fs; use std::fs;
use std::io::{self, BufRead, Seek, Read}; use std::io::{self, BufRead, Read, Seek};
use std::str::FromStr; use std::str::FromStr;
#[derive(Clone, Copy, Debug, PartialEq, Eq, FromPrimitive)] #[derive(Clone, Copy, Debug, PartialEq, Eq, FromPrimitive)]
@ -25,48 +24,36 @@ impl FromStr for Rps {
} }
} }
impl Ord for Rps { impl Rps {
fn cmp(&self, other: &Self) -> Ordering { fn versus(self, other: Self) -> Outcome {
match (self, other) { match (self, other) {
(x, y) if x == y => Ordering::Equal, (x, y) if x == y => Outcome::Draw,
(Rps::Rock, Rps::Scissors) | (Rps::Paper, Rps::Rock) | (Rps::Scissors, Rps::Paper) => { (Rps::Rock, Rps::Scissors) | (Rps::Paper, Rps::Rock) | (Rps::Scissors, Rps::Paper) => {
Ordering::Greater Outcome::Win
} }
_ => Ordering::Less, _ => Outcome::Lose,
} }
} }
}
impl PartialOrd for Rps {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Rps {
fn score(self, theirs: Rps) -> u32 { fn score(self, theirs: Rps) -> u32 {
self as u32 self as u32
+ 1 + 1
+ match self.cmp(&theirs) { + match self.versus(theirs) {
Ordering::Greater => 6, Outcome::Win => 6,
Ordering::Equal => 3, Outcome::Draw => 3,
Ordering::Less => 0, Outcome::Lose => 0,
} }
} }
fn play_against(self, win: bool) -> Rps {
FromPrimitive::from_i8((self as i8 + if win { 1 } else { -1 }).rem_euclid(3)).unwrap()
}
} }
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug, PartialEq)]
enum PlayStrat { enum Outcome {
Lose, Lose,
Draw, Draw,
Win, Win,
} }
impl FromStr for PlayStrat { impl FromStr for Outcome {
type Err = &'static str; type Err = &'static str;
fn from_str(input: &str) -> Result<Self, Self::Err> { fn from_str(input: &str) -> Result<Self, Self::Err> {
@ -74,18 +61,20 @@ impl FromStr for PlayStrat {
"X" => Ok(Self::Lose), "X" => Ok(Self::Lose),
"Y" => Ok(Self::Draw), "Y" => Ok(Self::Draw),
"Z" => Ok(Self::Win), "Z" => Ok(Self::Win),
_ => Err("Unknown strategy type!"), _ => Err("Unknown outcome!"),
} }
} }
} }
impl PlayStrat { impl Outcome {
fn against(self, theirs: Rps) -> Rps { fn against(self, theirs: Rps) -> Rps {
match self { let inc = match self {
Self::Draw => theirs, Outcome::Win => 1,
Self::Win => theirs.play_against(true), Outcome::Lose => -1,
Self::Lose => theirs.play_against(false), Outcome::Draw => 0,
} };
FromPrimitive::from_i8((theirs as i8 + inc).rem_euclid(3)).unwrap()
} }
} }
@ -122,10 +111,7 @@ fn part1(lines: std::io::Lines<&mut io::BufReader<fs::File>>) {
total_score += score; total_score += score;
println!( println!(
"Line \"{}\" - Theirs: {:?}, Mine: {:?}, score {}", "Line \"{}\" - Theirs: {:?}, Mine: {:?}, score {}",
line, line, theirs, mine, score,
theirs,
mine,
score,
); );
} }
@ -145,7 +131,7 @@ fn part2(lines: std::io::Lines<&mut io::BufReader<fs::File>>) {
let strat = split let strat = split
.next() .next()
.expect("Want two items per line") .expect("Want two items per line")
.parse::<PlayStrat>() .parse::<Outcome>()
.expect("Can't get my strategy"); .expect("Can't get my strategy");
let mine = strat.against(theirs); let mine = strat.against(theirs);
@ -154,11 +140,7 @@ fn part2(lines: std::io::Lines<&mut io::BufReader<fs::File>>) {
total_score += score; total_score += score;
println!( println!(
"Line \"{}\" - Theirs: {:?}, Strat: {:?}, Mine: {:?}, score {}", "Line \"{}\" - Theirs: {:?}, Strat: {:?}, Mine: {:?}, score {}",
line, line, theirs, strat, mine, score,
theirs,
strat,
mine,
score,
); );
} }
@ -169,6 +151,16 @@ fn part2(lines: std::io::Lines<&mut io::BufReader<fs::File>>) {
mod tests { mod tests {
use super::*; use super::*;
#[test]
fn rps() {
assert_eq!(Outcome::Win, Rps::Rock.versus(Rps::Scissors));
assert_eq!(Outcome::Win, Rps::Paper.versus(Rps::Rock));
assert_eq!(Outcome::Win, Rps::Scissors.versus(Rps::Paper));
assert_eq!(Outcome::Lose, Rps::Rock.versus(Rps::Paper));
assert_eq!(Outcome::Lose, Rps::Paper.versus(Rps::Scissors));
assert_eq!(Outcome::Lose, Rps::Scissors.versus(Rps::Rock));
}
#[test] #[test]
fn scores() { fn scores() {
assert_eq!(7, Rps::Rock.score(Rps::Scissors)); assert_eq!(7, Rps::Rock.score(Rps::Scissors));
@ -177,32 +169,22 @@ mod tests {
assert_eq!(6, Rps::Scissors.score(Rps::Scissors)); assert_eq!(6, Rps::Scissors.score(Rps::Scissors));
} }
#[test]
fn play_against() {
assert_eq!(Rps::Paper, Rps::Rock.play_against(true));
assert_eq!(Rps::Scissors, Rps::Paper.play_against(true));
assert_eq!(Rps::Rock, Rps::Scissors.play_against(true));
}
#[test] #[test]
fn strat_to_move() { fn strat_to_move() {
assert_eq!(Rps::Paper, PlayStrat::Win.against(Rps::Rock)); assert_eq!(Rps::Paper, Outcome::Win.against(Rps::Rock));
assert_eq!(Rps::Scissors, PlayStrat::Win.against(Rps::Paper)); assert_eq!(Rps::Scissors, Outcome::Win.against(Rps::Paper));
assert_eq!(Rps::Rock, PlayStrat::Win.against(Rps::Scissors)); assert_eq!(Rps::Rock, Outcome::Win.against(Rps::Scissors));
assert_eq!(Rps::Scissors, PlayStrat::Lose.against(Rps::Rock)); assert_eq!(Rps::Scissors, Outcome::Lose.against(Rps::Rock));
assert_eq!(Rps::Rock, PlayStrat::Lose.against(Rps::Paper)); assert_eq!(Rps::Rock, Outcome::Lose.against(Rps::Paper));
assert_eq!(Rps::Rock, PlayStrat::Draw.against(Rps::Rock)); assert_eq!(Rps::Rock, Outcome::Draw.against(Rps::Rock));
} }
#[test] #[test]
fn part_two_ex() { fn part_two_ex() {
assert_eq!(4, PlayStrat::Draw.against(Rps::Rock).score(Rps::Rock)); assert_eq!(4, Outcome::Draw.against(Rps::Rock).score(Rps::Rock));
assert_eq!(1, PlayStrat::Lose.against(Rps::Paper).score(Rps::Paper)); assert_eq!(1, Outcome::Lose.against(Rps::Paper).score(Rps::Paper));
assert_eq!( assert_eq!(7, Outcome::Win.against(Rps::Scissors).score(Rps::Scissors));
7,
PlayStrat::Win.against(Rps::Scissors).score(Rps::Scissors)
);
} }
} }