Finish AOC 2022 day 2
This commit is contained in:
parent
d506870214
commit
e491200ef1
|
@ -0,0 +1,14 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "common"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "day2"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"common",
|
||||
]
|
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "day2"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
common = { path = "../common" }
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,45 @@
|
|||
use common;
|
||||
|
||||
mod outcome;
|
||||
mod shape;
|
||||
|
||||
use outcome::Outcome;
|
||||
use shape::Shape;
|
||||
|
||||
fn main() {
|
||||
let input_file = common::parse_args_input_file(&mut std::env::args());
|
||||
let contents = std::fs::read_to_string(input_file).expect("Couldn't read contents of input file");
|
||||
|
||||
let mut plays = std::vec::Vec::<Play>::new();
|
||||
for line in contents.lines() {
|
||||
if line.eq("") {
|
||||
continue;
|
||||
}
|
||||
let chars: std::vec::Vec<char> = line.chars().collect();
|
||||
assert_eq!(chars.len(), 3);
|
||||
plays.push(Play {
|
||||
opponent: Shape::from_hint(chars[0]),
|
||||
hinted_response: Shape::from_hint(chars[2]),
|
||||
hinted_outcome: Outcome::from_hint(chars[2]),
|
||||
});
|
||||
}
|
||||
let mut score: u32 = 0;
|
||||
for play in &plays {
|
||||
score += play.hinted_response.score(&play.opponent);
|
||||
}
|
||||
println!("[PART 1] Score if played as suggested: {}", score);
|
||||
|
||||
score = 0;
|
||||
for play in &plays {
|
||||
let shape = play.opponent.find_shape_to_achieve_outcome(&play.hinted_outcome);
|
||||
score += shape.score(&play.opponent);
|
||||
}
|
||||
println!("[PART 2] Score if played with hinted outcomes: {}", score);
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Play {
|
||||
opponent: Shape,
|
||||
hinted_response: Shape,
|
||||
hinted_outcome: Outcome,
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
#[derive(Debug, PartialEq)]
|
||||
pub enum Outcome {
|
||||
Loss,
|
||||
Draw,
|
||||
Win,
|
||||
}
|
||||
|
||||
impl Outcome {
|
||||
pub fn from_hint(c: char) -> Self {
|
||||
return match c {
|
||||
'X' => Outcome::Loss,
|
||||
'Y' => Outcome::Draw,
|
||||
'Z' => Outcome::Win,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn value(&self) -> u32 {
|
||||
return match self {
|
||||
Self::Loss => 0,
|
||||
Self::Draw => 3,
|
||||
Self::Win => 6,
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
use crate::Outcome;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Shape {
|
||||
Rock,
|
||||
Paper,
|
||||
Scissors,
|
||||
}
|
||||
|
||||
impl Shape {
|
||||
pub fn find_shape_to_achieve_outcome(&self, outcome: &Outcome) -> Self {
|
||||
return match outcome {
|
||||
Outcome::Draw => self.clone(),
|
||||
Outcome::Win => {
|
||||
match self {
|
||||
Shape::Rock => Shape::Paper,
|
||||
Shape::Paper => Shape::Scissors,
|
||||
Shape::Scissors => Shape::Rock,
|
||||
}
|
||||
},
|
||||
Outcome::Loss => {
|
||||
match self {
|
||||
Shape::Rock => Shape::Scissors,
|
||||
Shape::Paper => Shape::Rock,
|
||||
Shape::Scissors => Shape::Paper,
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn from_hint(hint: char) -> Self {
|
||||
return match hint {
|
||||
'A' | 'X' => Shape::Rock,
|
||||
'B' | 'Y' => Shape::Paper,
|
||||
'C' | 'Z' => Shape::Scissors,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn score(&self, other: &Shape) -> u32 {
|
||||
let mut s = self.value();
|
||||
s += self.vs(other).value();
|
||||
return s;
|
||||
}
|
||||
|
||||
fn value(&self) -> u32 {
|
||||
return match self {
|
||||
Self::Rock => 1,
|
||||
Self::Paper => 2,
|
||||
Self::Scissors => 3,
|
||||
};
|
||||
}
|
||||
|
||||
fn vs(&self, other: &Shape) -> Outcome {
|
||||
if *self == *other {
|
||||
return Outcome::Draw;
|
||||
}
|
||||
return match self {
|
||||
Shape::Rock => {
|
||||
match other {
|
||||
Shape::Scissors => Outcome::Win,
|
||||
Shape::Paper => Outcome::Loss,
|
||||
Shape::Rock => unreachable!(),
|
||||
}
|
||||
},
|
||||
Shape::Paper => {
|
||||
match other {
|
||||
Shape::Rock => Outcome::Win,
|
||||
Shape::Scissors => Outcome::Loss,
|
||||
Shape::Paper => unreachable!(),
|
||||
}
|
||||
},
|
||||
Shape::Scissors => {
|
||||
match other {
|
||||
Shape::Rock => Outcome::Loss,
|
||||
Shape::Paper => Outcome::Win,
|
||||
Shape::Scissors => unreachable!(),
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_rock_outcomes() {
|
||||
let play = Shape::Rock;
|
||||
assert_eq!(play.vs(Shape::Rock), Outcome::Draw);
|
||||
assert_eq!(play.vs(Shape::Paper), Outcome::Loss);
|
||||
assert_eq!(play.vs(Shape::Scissors), Outcome::Win);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_paper_outcomes() {
|
||||
let play = Shape::Paper;
|
||||
assert_eq!(play.vs(Shape::Rock), Outcome::Win);
|
||||
assert_eq!(play.vs(Shape::Paper), Outcome::Draw);
|
||||
assert_eq!(play.vs(Shape::Scissors), Outcome::Loss);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_scissor_outcomes() {
|
||||
let play = Shape::Scissors;
|
||||
assert_eq!(play.vs(Shape::Rock), Outcome::Loss);
|
||||
assert_eq!(play.vs(Shape::Paper), Outcome::Win);
|
||||
assert_eq!(play.vs(Shape::Scissors), Outcome::Draw);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_score() {
|
||||
assert_eq!(Shape::Paper.score(Shape::Rock), 8);
|
||||
assert_eq!(Shape::Rock.score(Shape::Paper), 1);
|
||||
assert_eq!(Shape::Scissors.score(Shape::Scissors), 6);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_finding_shapes_for_outcome() {
|
||||
assert_eq!(Shape::Rock.find_shape_to_achieve_outcome(&Outcome::Draw), Shape::Rock);
|
||||
assert_eq!(Shape::Paper.find_shape_to_achieve_outcome(&Outcome::Loss), Shape::Rock);
|
||||
assert_eq!(Shape::Paper.find_shape_to_achieve_outcome(&Outcome::Win), Shape::Scissors);
|
||||
assert_eq!(Shape::Scissors.find_shape_to_achieve_outcome(&Outcome::Loss), Shape::Paper);
|
||||
assert_eq!(Shape::Scissors.find_shape_to_achieve_outcome(&Outcome::Win), Shape::Rock);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "common"
|
||||
version = "0.1.0"
|
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "common"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
|
@ -0,0 +1,16 @@
|
|||
pub fn parse_args_input_file(args: &mut std::env::Args) -> String {
|
||||
let mut input_file = Some("input".to_string());
|
||||
while args.len() > 0 {
|
||||
let arg = args.nth(0);
|
||||
if arg.unwrap().eq("-f") {
|
||||
let value = args.nth(0);
|
||||
if value.is_some() {
|
||||
input_file = value;
|
||||
}
|
||||
else {
|
||||
println!("No value after argument: '-f'");
|
||||
}
|
||||
}
|
||||
}
|
||||
return input_file.unwrap();
|
||||
}
|
Loading…
Reference in New Issue