Finish AOC 2022 day 2

This commit is contained in:
Kienan Stewart 2022-12-02 10:24:50 -05:00
parent d506870214
commit e491200ef1
9 changed files with 2751 additions and 0 deletions

14
2022/2/Cargo.lock generated Normal file
View File

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

9
2022/2/Cargo.toml Normal file
View File

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

2500
2022/2/input Normal file

File diff suppressed because it is too large Load Diff

45
2022/2/src/main.rs Normal file
View File

@ -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,
}

25
2022/2/src/outcome.rs Normal file
View File

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

127
2022/2/src/shape.rs Normal file
View File

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

7
2022/common/Cargo.lock generated Normal file
View File

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

8
2022/common/Cargo.toml Normal file
View File

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

16
2022/common/src/lib.rs Normal file
View File

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