1
0
Fork 0

day(02): refactor

Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
Matej Focko 2022-12-02 15:20:48 +01:00
parent dbc155fd44
commit eea97c6e7b
Signed by: mfocko
GPG key ID: 7C47D46246790496

View file

@ -3,11 +3,12 @@ use std::str::FromStr;
use aoc_2022::*; use aoc_2022::*;
use color_eyre::eyre::Result; use color_eyre::eyre::Result;
use itertools::Itertools;
use thiserror::Error; use thiserror::Error;
use tracing::*; use tracing::*;
use tracing_subscriber::EnvFilter; use tracing_subscriber::EnvFilter;
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Shape { enum Shape {
Rock, Rock,
Paper, Paper,
@ -28,7 +29,7 @@ impl Shape {
enum ShapeError { enum ShapeError {
#[error("empty string given")] #[error("empty string given")]
Empty, Empty,
#[error("unknown shape {0}")] #[error("unknown shape {0}")]
UnknownShape(String), UnknownShape(String),
} }
@ -85,20 +86,53 @@ impl FromStr for Round {
} }
} }
fn find_strategy<P>(predicate: P) -> (usize, (Shape, Shape))
where
P: FnMut(&(usize, (Shape, Shape))) -> bool,
{
// R P S
// R 3 0 6
// P 6 3 0
// S 0 6 3
vec![
// Loss
(Shape::Rock, Shape::Paper),
(Shape::Paper, Shape::Scissors),
(Shape::Scissors, Shape::Rock),
// Draw
(Shape::Rock, Shape::Rock),
(Shape::Paper, Shape::Paper),
(Shape::Scissors, Shape::Scissors),
// Win
(Shape::Rock, Shape::Scissors),
(Shape::Paper, Shape::Rock),
(Shape::Scissors, Shape::Paper),
]
.into_iter()
.enumerate()
.find_or_first(predicate)
.unwrap()
}
fn find_result(strategy: &(Shape, Shape)) -> i32 {
3 * (find_strategy(|&(_, st)| st == *strategy).0 as i32 / 3)
}
fn find_result_for_outcome(opponent: Shape, outcome: Outcome) -> i32 {
let range = match outcome {
Outcome::Lose => 0..3,
Outcome::Draw => 3..6,
Outcome::Win => 6..9,
};
let (i, (shape, _)) = find_strategy(|&(i, (_, op))| range.contains(&i) && op == opponent);
3 * (i as i32 / 3) + shape.score()
}
impl Round { impl Round {
fn score(&self) -> i32 { fn score(&self) -> i32 {
let shape_score = self.me.score(); let shape_score = self.me.score();
let result_score = find_result(&(self.me, self.opponent));
let result_score = match (self.me, self.opponent) {
(Shape::Scissors, Shape::Paper) => 6,
(Shape::Paper, Shape::Rock) => 6,
(Shape::Rock, Shape::Scissors) => 6,
(Shape::Paper, Shape::Scissors) => 0,
(Shape::Rock, Shape::Paper) => 0,
(Shape::Scissors, Shape::Rock) => 0,
_ => 3,
};
shape_score + result_score shape_score + result_score
} }
@ -111,23 +145,7 @@ impl Round {
} }
fn expected_score(&self) -> i32 { fn expected_score(&self) -> i32 {
let result_score = match self.expected_outcome() { find_result_for_outcome(self.opponent, self.expected_outcome())
Outcome::Lose => 0,
Outcome::Draw => 3,
Outcome::Win => 6,
};
let shape_score = match (self.expected_outcome(), self.opponent) {
(Outcome::Lose, Shape::Rock) => Shape::Scissors.score(),
(Outcome::Lose, Shape::Paper) => Shape::Rock.score(),
(Outcome::Lose, Shape::Scissors) => Shape::Paper.score(),
(Outcome::Win, Shape::Rock) => Shape::Paper.score(),
(Outcome::Win, Shape::Paper) => Shape::Scissors.score(),
(Outcome::Win, Shape::Scissors) => Shape::Rock.score(),
_ => self.opponent.score(),
};
result_score + shape_score
} }
} }