1
0
Fork 0

Working submission (part 2)

This commit is contained in:
Vivianne 2022-12-02 01:42:29 -08:00
parent 0900b54c13
commit 6d5f7f6728
4 changed files with 2733 additions and 1 deletions

65
Cargo.lock generated
View File

@ -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"

View File

@ -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"

2500
etc/p02.txt Normal file

File diff suppressed because it is too large Load Diff

165
src/bin/p02.rs Normal file
View File

@ -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)
);
}
}