Skip to content

Instantly share code, notes, and snippets.

@Philogy
Last active June 26, 2023 20:16
Show Gist options
  • Save Philogy/2152684a634ca08b1da51803c69ae23c to your computer and use it in GitHub Desktop.
Save Philogy/2152684a634ca08b1da51803c69ae23c to your computer and use it in GitHub Desktop.
Advent of Code 2022 (Day 2) in Rust
use std::cmp::{Ordering, PartialOrd};
use std::fs;
#[derive(Debug, PartialEq, Eq, Clone)]
enum Move {
Rock,
Paper,
Scissors,
}
impl Move {
fn get_winning_move(&self) -> Move {
match self {
Move::Rock => Move::Paper,
Move::Paper => Move::Scissors,
Move::Scissors => Move::Rock,
}
}
fn get_losing_move(&self) -> Move {
match self {
Move::Rock => Move::Scissors,
Move::Paper => Move::Rock,
Move::Scissors => Move::Paper,
}
}
fn play_value(&self) -> i32 {
match self {
Move::Rock => 1,
Move::Paper => 2,
Move::Scissors => 3,
}
}
fn score_game(&self, opposing_move: &Move) -> i32 {
match self.partial_cmp(opposing_move).unwrap() {
Ordering::Equal => 3,
Ordering::Greater => 6,
Ordering::Less => 0,
}
}
fn score_whole(&self, opposing_move: &Move) -> i32 {
self.play_value() + self.score_game(opposing_move)
}
fn parse_opponent(mv: &str) -> Result<Move, String> {
match mv {
"A" => Ok(Move::Rock),
"B" => Ok(Move::Paper),
"C" => Ok(Move::Scissors),
_ => Err(format!("Failed to parse opponent move '{mv}'")),
}
}
fn parse_naive(mv: &str) -> Result<Move, String> {
match mv {
"X" => Ok(Move::Rock),
"Y" => Ok(Move::Paper),
"Z" => Ok(Move::Scissors),
_ => Err(format!("Failed to parse naive move '{mv}'")),
}
}
}
impl PartialOrd for Move {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(if self.get_losing_move() == *other {
Ordering::Greater
} else if self.get_winning_move() == *other {
Ordering::Less
} else {
Ordering::Equal
})
}
}
fn evaluate_strategy(
input: &String,
strategy: fn(&str, &Move) -> Result<Move, String>,
) -> Result<i32, String> {
Ok(input
.lines()
.map(|line| {
let parts = line.split_whitespace().collect::<Vec<&str>>();
let opponent_move = Move::parse_opponent(parts[0])?;
let my_move = strategy(parts[1], &opponent_move)?;
Ok(my_move.score_whole(&opponent_move))
})
.collect::<Result<Vec<i32>, String>>()?
.iter()
.sum())
}
/// # Advent Of Code (2022 Day 2) [link](https://adventofcode.com/2022/day/2).
///
/// Challenge is you receive an input which represents a transcript of Rock-Paper-Scissors Games:
///
/// ```
/// A X game 1
/// B Z game 2
/// C Z ...
/// B Z
/// B Z
/// A Y
/// A Y
/// A Z
/// A Y
/// ```
///
/// Your opponent's moves are encoded as A, B, C for Rock, Paper and Scissors respectively. Games
/// are scored, 6 for a win, 3 for a tie and 0 for a loss. Your choice gives you an additional 1,
/// 2 or 3 points for Rock, Paper and Scissors respectively.
///
/// ## Part 1
///
/// Your strategy is to interpret X, Y and Z as moves directly whereby they represent Rock, Paper,
/// Scissors respectively. This is labeled the "naive" strategy in the code below. You must then compute
/// the total score for your strategy across all games.
///
/// ## Part 2
///
/// In this part your strategy is to go for a loss at 'X', a tie at 'Y' and a win at 'Z'. For the
/// second part you're also meant to compute the total score across all games, this strategy is
/// labeled the "actual" strategy in the code below.
///
fn main() {
let input = fs::read_to_string("./src/input.txt").unwrap();
match evaluate_strategy(&input, |move_str, _| Move::parse_naive(move_str)) {
Ok(score_naive) => println!("Naive score: {score_naive}"),
Err(err) => println!("Error occured while evaluating naive strategy: {err:?}"),
}
match evaluate_strategy(&input, |move_str, opponent_move| match move_str {
"X" => Ok(opponent_move.get_losing_move()),
"Y" => Ok(opponent_move.clone()),
"Z" => Ok(opponent_move.get_winning_move()),
_ => Err(format!("Failed to parse move '{move_str}'")),
}) {
Ok(score_actual) => println!("Actual score: {score_actual}"),
Err(err) => println!("Error occured while evaluating actual strategy: {err:?}"),
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment