day(02): add initial solution
Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
parent
27db9907d4
commit
5e8669da00
2 changed files with 159 additions and 0 deletions
3
samples/day02.txt
Normal file
3
samples/day02.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
A Y
|
||||
B X
|
||||
C Z
|
156
src/bin/day02.rs
Normal file
156
src/bin/day02.rs
Normal 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);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue