1
0
Fork 0

day(02): add initial solution

Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
Matej Focko 2022-12-02 10:24:20 +01:00
parent 27db9907d4
commit 5e8669da00
Signed by: mfocko
GPG key ID: 7C47D46246790496
2 changed files with 159 additions and 0 deletions

3
samples/day02.txt Normal file
View file

@ -0,0 +1,3 @@
A Y
B X
C Z

156
src/bin/day02.rs Normal file
View file

@ -0,0 +1,156 @@
use aoc_2022::*;
use color_eyre::eyre::Result;
use itertools::Itertools;
use tracing::*;
use tracing_subscriber::EnvFilter;
#[derive(Debug, Clone, Copy)]
enum Shape {
Rock,
Paper,
Scissors,
}
impl Shape {
fn score(&self) -> i32 {
match self {
Shape::Rock => 1,
Shape::Paper => 2,
Shape::Scissors => 3,
}
}
}
#[derive(Debug, Clone, Copy)]
enum Outcome {
Lose,
Draw,
Win,
}
#[derive(Debug, Clone, Copy)]
struct Round {
opponent: Shape,
me: Shape,
}
impl Round {
fn score(&self) -> i32 {
let shape_score = self.me.score();
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
}
fn expected_outcome(&self) -> Outcome {
match self.me {
Shape::Rock => Outcome::Lose,
Shape::Paper => Outcome::Draw,
Shape::Scissors => Outcome::Win,
}
}
fn expected_score(&self) -> i32 {
let result_score = match 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
}
}
type Input = Vec<Round>;
type Output = i32;
fn part_1(input: &Input) -> Output {
input.iter().map(Round::score).sum()
}
fn part_2(input: &Input) -> Output {
input.iter().map(Round::expected_score).sum()
}
fn parse_input(pathname: &str) -> Input {
file_to_lines(pathname)
.iter()
.map(|s| {
let mut split_str = s.split(" ");
let opponent = split_str.next().unwrap();
let me = split_str.next().unwrap();
Round {
opponent: match opponent {
"A" => Shape::Rock,
"B" => Shape::Paper,
"C" => Shape::Scissors,
_ => panic!("invalid choice"),
},
me: match me {
"X" => Shape::Rock,
"Y" => Shape::Paper,
"Z" => Shape::Scissors,
_ => panic!("invalid choice"),
},
}
})
.collect()
}
fn main() -> Result<()> {
tracing_subscriber::fmt()
.with_env_filter(EnvFilter::from_default_env())
.with_target(false)
.with_file(true)
.with_line_number(true)
.without_time()
.compact()
.init();
color_eyre::install()?;
let input = parse_input("inputs/day02.txt");
info!("Part 1: {}", part_1(&input));
info!("Part 2: {}", part_2(&input));
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part_1() {
let sample = parse_input("samples/day02.txt");
assert_eq!(part_1(&sample), 15);
}
#[test]
fn test_part_2() {
let sample = parse_input("samples/day02.txt");
assert_eq!(part_2(&sample), 12);
}
}