126 lines
3.2 KiB
Rust
126 lines
3.2 KiB
Rust
use std::str::FromStr;
|
|
|
|
use aoc_runner_derive::{aoc, aoc_generator};
|
|
|
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
|
pub enum Choice {
|
|
Rock,
|
|
Paper,
|
|
Scissors,
|
|
}
|
|
|
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
|
pub enum Outcome {
|
|
Win,
|
|
Loose,
|
|
Draw,
|
|
}
|
|
|
|
impl Outcome {
|
|
fn other(&self, choice: &Choice) -> Choice {
|
|
match (self, choice) {
|
|
(Outcome::Win, Choice::Rock) => Choice::Paper,
|
|
(Outcome::Win, Choice::Paper) => Choice::Scissors,
|
|
(Outcome::Win, Choice::Scissors) => Choice::Rock,
|
|
(Outcome::Loose, Choice::Rock) => Choice::Scissors,
|
|
(Outcome::Loose, Choice::Paper) => Choice::Rock,
|
|
(Outcome::Loose, Choice::Scissors) => Choice::Paper,
|
|
(Outcome::Draw, other) => *other,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<Outcome> for usize {
|
|
fn from(val: Outcome) -> Self {
|
|
match val {
|
|
Outcome::Win => 6,
|
|
Outcome::Loose => 0,
|
|
Outcome::Draw => 3,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<&Choice> for Outcome {
|
|
fn from(value: &Choice) -> Self {
|
|
match value {
|
|
Choice::Rock => Outcome::Loose,
|
|
Choice::Paper => Outcome::Draw,
|
|
Choice::Scissors => Outcome::Win,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Choice {
|
|
fn shape_score(&self) -> usize {
|
|
match self {
|
|
Choice::Rock => 1,
|
|
Choice::Paper => 2,
|
|
Choice::Scissors => 3,
|
|
}
|
|
}
|
|
fn outcome(&self, other: &Self) -> Outcome {
|
|
match (self, other) {
|
|
(Choice::Rock, Choice::Scissors) => Outcome::Win,
|
|
(Choice::Paper, Choice::Rock) => Outcome::Win,
|
|
(Choice::Scissors, Choice::Paper) => Outcome::Win,
|
|
(Choice::Rock, Choice::Paper) => Outcome::Loose,
|
|
(Choice::Paper, Choice::Scissors) => Outcome::Loose,
|
|
(Choice::Scissors, Choice::Rock) => Outcome::Loose,
|
|
_ => Outcome::Draw,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl FromStr for Choice {
|
|
type Err = ();
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
match s.to_ascii_uppercase().as_str() {
|
|
"A" | "X" => Ok(Self::Rock),
|
|
"B" | "Y" => Ok(Self::Paper),
|
|
"C" | "Z" => Ok(Self::Scissors),
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[aoc_generator(day2)]
|
|
pub fn input_generator(input: &str) -> Vec<(Choice, Choice)> {
|
|
input
|
|
.lines()
|
|
.map(|line| {
|
|
let rule = line
|
|
.split_ascii_whitespace()
|
|
.map(|r| r.parse().unwrap())
|
|
.collect::<Vec<Choice>>();
|
|
(rule[0], rule[1])
|
|
})
|
|
.collect()
|
|
}
|
|
|
|
#[aoc(day2, part1)]
|
|
pub fn solve_part1(input: &[(Choice, Choice)]) -> usize {
|
|
input
|
|
.iter()
|
|
.map(|(other, mine)| {
|
|
let shape_score = mine.shape_score();
|
|
let outcome: usize = mine.outcome(other).into();
|
|
shape_score + outcome
|
|
})
|
|
.sum()
|
|
}
|
|
|
|
#[aoc(day2, part2)]
|
|
pub fn solve_part2(input: &[(Choice, Choice)]) -> usize {
|
|
input
|
|
.iter()
|
|
.map(|(other, goal)| {
|
|
let goal: Outcome = goal.into();
|
|
let mine = goal.other(other);
|
|
let shape_score = mine.shape_score();
|
|
let outcome: usize = goal.into();
|
|
shape_score + outcome
|
|
})
|
|
.sum()
|
|
}
|