1
0
Fork 0
AdvenOfCode2022/src/prob2/mod.rs

169 lines
4.4 KiB
Rust

#[derive(PartialEq, Eq)]
pub enum Play {
Rock,
Paper,
Scissors,
}
#[derive(Copy, Clone)]
enum ResultPlay {
Win,
Draw,
Loss,
}
impl Into<char> for Play {
fn into(self) -> char {
match self {
Play::Rock => 'X',
Play::Paper => 'Y',
Play::Scissors => 'Z',
}
}
}
impl Into<i32> for Play {
fn into(self) -> i32 {
match self {
Play::Rock => 1,
Play::Paper => 2,
Play::Scissors => 3,
}
}
}
impl From<char> for Play {
fn from(letter: char) -> Self {
match letter {
'A' => Play::Rock,
'B' => Play::Paper,
'C' => Play::Scissors,
'X' => Play::Rock,
'Y' => Play::Paper,
'Z' => Play::Scissors,
other => panic!("Only A, B, C, X, Y or Z letters are available. Had {other}"),
}
}
}
impl Into<i32> for ResultPlay {
fn into(self) -> i32 {
match self {
ResultPlay::Win => 6,
ResultPlay::Draw => 3,
ResultPlay::Loss => 0,
}
}
}
pub fn round_score(play: char, counter_play: char) -> i32 {
let coup = Play::from(play); // translate to the play
let counter = Play::from(counter_play); // translate to the play
if coup == counter {
let draw: i32 = ResultPlay::Draw.into();
let result: i32 = counter.into();
draw + result
} else {
use Play::*;
use ResultPlay::*;
let loss: i32 = Loss.into();
let win: i32 = Win.into();
match (&coup, &counter) {
(Rock, Paper) => {
let result: i32 = counter.into();
win + result
}
(Rock, Scissors) => {
let result: i32 = counter.into();
loss + result
}
(Paper, Rock) => {
let result: i32 = counter.into();
loss + result
}
(Paper, Scissors) => {
let result: i32 = counter.into();
win + result
}
(Scissors, Rock) => {
let result: i32 = counter.into();
win + result
}
(Scissors, Paper) => {
let result: i32 = counter.into();
loss + result
}
_ => panic!("Case not covered, impossible to reach."),
}
}
}
fn choose_answer(strat: &ResultPlay, input: Play) -> Play {
use Play::*;
use ResultPlay::*;
match strat {
Loss => match input {
Rock => Scissors,
Paper => Rock,
Scissors => Paper,
},
Draw => input,
Win => match input {
Rock => Paper,
Paper => Scissors,
Scissors => Rock,
},
}
}
fn getting_score(game_output: &ResultPlay, play: Play) -> i32 {
let game: i32 = (*game_output).into();
let play_result: i32 = play.into();
game + play_result
}
pub fn second_strat(play: char, strat: char) -> i32 {
let coup = Play::from(play);
let response = match strat {
'X' => ResultPlay::Loss,
'Y' => ResultPlay::Draw,
'Z' => ResultPlay::Win,
other => panic!("Wrong letter {other}"),
};
getting_score(&response, choose_answer(&response, coup))
}
pub fn solve_part1(file_path: &str) -> i32 {
let contents =
std::fs::read_to_string(file_path).expect("Please provide a text file as an argument.");
let lines: Vec<&str> = contents.split('\n').collect();
lines
.iter()
.map(|line| {
let mut line_iter = line.chars();
let first: char = line_iter.next().unwrap_or('R');
let last: char = line_iter.last().unwrap_or('R');
round_score(first, last)
})
.collect::<Vec<i32>>()
.iter()
.sum()
}
pub fn solve_part2(file_path: &str) -> i32 {
let contents =
std::fs::read_to_string(file_path).expect("Please provide a text file as an argument.");
let lines: Vec<&str> = contents.split('\n').collect();
lines
.iter()
.map(|line| {
let mut line_iter = line.chars();
let first: char = line_iter.next().unwrap_or('R');
let last: char = line_iter.last().unwrap_or('R');
second_strat(first, last)
})
.collect::<Vec<i32>>()
.iter()
.sum()
}