day(02): refactor
Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
parent
dbc155fd44
commit
eea97c6e7b
1 changed files with 48 additions and 30 deletions
|
@ -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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue