169 lines
4.4 KiB
Rust
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()
|
|
}
|