Working submission (part 2)
This commit is contained in:
parent
0900b54c13
commit
6d5f7f6728
|
@ -5,3 +5,68 @@ version = 3
|
|||
[[package]]
|
||||
name = "aoc-vv"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"num-derive",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "num-derive"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eafd0b45c5537c3ba526f79d3e75120036502bebacbb3f3220914067ce39dbf2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.4.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.6.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.15.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
name = "aoc-vv"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
default-run = "p01"
|
||||
default-run = "p02"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
num-traits = "0.2"
|
||||
num-derive = "0.2"
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,165 @@
|
|||
use num_derive::FromPrimitive;
|
||||
use num_traits::FromPrimitive;
|
||||
use std::cmp::Ordering;
|
||||
use std::fs;
|
||||
use std::io::{self, BufRead};
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, FromPrimitive)]
|
||||
enum RPS {
|
||||
Rock = 0,
|
||||
Paper,
|
||||
Scissors,
|
||||
}
|
||||
|
||||
impl FromStr for RPS {
|
||||
type Err = &'static str;
|
||||
|
||||
fn from_str(input: &str) -> Result<Self, Self::Err> {
|
||||
match input {
|
||||
"A" | "X" => Ok(RPS::Rock),
|
||||
"B" | "Y" => Ok(RPS::Paper),
|
||||
"C" | "Z" => Ok(RPS::Scissors),
|
||||
_ => Err("Unknown move type!"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for RPS {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
match (self, other) {
|
||||
(x, y) if x == y => Ordering::Equal,
|
||||
(RPS::Rock, RPS::Scissors) | (RPS::Paper, RPS::Rock) | (RPS::Scissors, RPS::Paper) => {
|
||||
Ordering::Greater
|
||||
}
|
||||
_ => Ordering::Less,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RPS {
|
||||
fn score(self, theirs: RPS) -> u32 {
|
||||
self as u32
|
||||
+ 1
|
||||
+ match self.cmp(&theirs) {
|
||||
Ordering::Greater => 6,
|
||||
Ordering::Equal => 3,
|
||||
Ordering::Less => 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)]
|
||||
enum PlayStrat {
|
||||
Lose,
|
||||
Draw,
|
||||
Win,
|
||||
}
|
||||
|
||||
impl FromStr for PlayStrat {
|
||||
type Err = &'static str;
|
||||
|
||||
fn from_str(input: &str) -> Result<Self, Self::Err> {
|
||||
match input {
|
||||
"X" => Ok(Self::Lose),
|
||||
"Y" => Ok(Self::Draw),
|
||||
"Z" => Ok(Self::Win),
|
||||
_ => Err("Unknown strategy type!"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PlayStrat {
|
||||
fn against(self, theirs: RPS) -> RPS {
|
||||
match self {
|
||||
Self::Draw => theirs,
|
||||
Self::Win => theirs.play_against(true),
|
||||
Self::Lose => theirs.play_against(false),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let filename = "etc/p02.txt";
|
||||
let file = fs::File::open(filename).expect("Can't open file");
|
||||
let lines = io::BufReader::new(file).lines();
|
||||
|
||||
let mut total_score: u32 = 0;
|
||||
for l in lines {
|
||||
let line = l.expect("Can't read line.");
|
||||
let mut split = line.split_ascii_whitespace();
|
||||
let theirs = split
|
||||
.next()
|
||||
.expect("Want two items per line")
|
||||
.parse::<RPS>()
|
||||
.expect("Can't get their move");
|
||||
let strat = split
|
||||
.next()
|
||||
.expect("Want two items per line")
|
||||
.parse::<PlayStrat>()
|
||||
.expect("Can't get my strategy");
|
||||
|
||||
let mine = strat.against(theirs);
|
||||
|
||||
let score = mine.score(theirs);
|
||||
total_score += score;
|
||||
println!(
|
||||
"Line \"{}\" - Theirs: {:?}, Strat: {:?}, Mine: {:?} ({:?}), score {} (so far {})",
|
||||
line,
|
||||
theirs,
|
||||
strat,
|
||||
mine,
|
||||
mine.cmp(&theirs),
|
||||
score,
|
||||
total_score,
|
||||
);
|
||||
}
|
||||
|
||||
println!("Total score is {}", total_score);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn scores() {
|
||||
assert_eq!(7, RPS::Rock.score(RPS::Scissors));
|
||||
assert_eq!(8, RPS::Paper.score(RPS::Rock));
|
||||
assert_eq!(1, RPS::Rock.score(RPS::Paper));
|
||||
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]
|
||||
fn strat_to_move() {
|
||||
assert_eq!(RPS::Paper, PlayStrat::Win.against(RPS::Rock));
|
||||
assert_eq!(RPS::Scissors, PlayStrat::Win.against(RPS::Paper));
|
||||
assert_eq!(RPS::Rock, PlayStrat::Win.against(RPS::Scissors));
|
||||
|
||||
assert_eq!(RPS::Scissors, PlayStrat::Lose.against(RPS::Rock));
|
||||
assert_eq!(RPS::Rock, PlayStrat::Lose.against(RPS::Paper));
|
||||
|
||||
assert_eq!(RPS::Rock, PlayStrat::Draw.against(RPS::Rock));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part_two_ex() {
|
||||
assert_eq!(4, PlayStrat::Draw.against(RPS::Rock).score(RPS::Rock));
|
||||
assert_eq!(1, PlayStrat::Lose.against(RPS::Paper).score(RPS::Paper));
|
||||
assert_eq!(
|
||||
7,
|
||||
PlayStrat::Win.against(RPS::Scissors).score(RPS::Scissors)
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue