Renamed things for clarity and stopped using Ord
This commit is contained in:
parent
a5cc701cce
commit
b6d2240d51
106
src/bin/p02.rs
106
src/bin/p02.rs
|
@ -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)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue