Day 2 solution!
This commit is contained in:
parent
4cd7570ba9
commit
00944b19b6
2 changed files with 2677 additions and 0 deletions
2500
2022/Data/day2-input.txt
Normal file
2500
2022/Data/day2-input.txt
Normal file
File diff suppressed because it is too large
Load diff
177
2022/aoc2022/src/day2.rs
Normal file
177
2022/aoc2022/src/day2.rs
Normal file
|
@ -0,0 +1,177 @@
|
|||
use std::io::Result;
|
||||
|
||||
use crate::file::line_reader_for_file;
|
||||
|
||||
const SCORE_FOR_ROCK: i32 = 1;
|
||||
const SCORE_FOR_PAPER: i32 = 2;
|
||||
const SCORE_FOR_SCISSORS: i32 = 3;
|
||||
|
||||
const SCORE_FOR_WIN: i32 = 6;
|
||||
const SCORE_FOR_DRAW: i32 = 3;
|
||||
const SCORE_FOR_LOSS: i32 = 0;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, PartialOrd)]
|
||||
enum Shape { Rock, Paper, Scissors }
|
||||
|
||||
impl Shape {
|
||||
fn part1_from_string(s: &str) -> Option<Shape> {
|
||||
if s == "A" || s == "X" {
|
||||
Some(Shape::Rock)
|
||||
} else if s == "B" || s == "Y" {
|
||||
Some(Shape::Paper)
|
||||
} else if s == "C" || s == "Z" {
|
||||
Some(Shape::Scissors)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn part2_from_string(s: &str) -> Option<Shape> {
|
||||
if s == "A" {
|
||||
Some(Shape::Rock)
|
||||
} else if s == "B" {
|
||||
Some(Shape::Paper)
|
||||
} else if s == "C" {
|
||||
Some(Shape::Scissors)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn part2_from_shape_and_outcome(shape: Shape, outcome: Outcome) -> Shape {
|
||||
match outcome {
|
||||
Outcome::Win => shape.shape_to_win(),
|
||||
Outcome::Draw => shape.shape_to_draw(),
|
||||
Outcome::Loss => shape.shape_to_lose(),
|
||||
}
|
||||
}
|
||||
|
||||
fn shape_to_win(&self) -> Shape {
|
||||
match self {
|
||||
Shape::Rock => Shape::Paper,
|
||||
Shape::Paper => Shape::Scissors,
|
||||
Shape::Scissors => Shape::Rock,
|
||||
}
|
||||
}
|
||||
|
||||
fn shape_to_draw(&self) -> Shape {
|
||||
*self
|
||||
}
|
||||
|
||||
fn shape_to_lose(&self) -> Shape {
|
||||
match self {
|
||||
Shape::Rock => Shape::Scissors,
|
||||
Shape::Paper => Shape::Rock,
|
||||
Shape::Scissors => Shape::Paper,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, PartialOrd)]
|
||||
enum Outcome { Win, Draw, Loss }
|
||||
|
||||
impl Outcome {
|
||||
fn part2_from_string(s: &str) -> Option<Outcome> {
|
||||
match s {
|
||||
"X" => Some(Outcome::Loss),
|
||||
"Y" => Some(Outcome::Draw),
|
||||
"Z" => Some(Outcome::Win),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
fn with_shapes(opponent: Shape, me: Shape) -> Outcome {
|
||||
match (opponent, me) {
|
||||
(Shape::Rock, Shape::Rock) => Outcome::Draw,
|
||||
(Shape::Rock, Shape::Paper) => Outcome::Win,
|
||||
(Shape::Rock, Shape::Scissors) => Outcome::Loss,
|
||||
(Shape::Paper, Shape::Rock) => Outcome::Loss,
|
||||
(Shape::Paper, Shape::Paper) => Outcome::Draw,
|
||||
(Shape::Paper, Shape::Scissors) => Outcome::Win,
|
||||
(Shape::Scissors, Shape::Rock) => Outcome::Win,
|
||||
(Shape::Scissors, Shape::Paper) => Outcome::Loss,
|
||||
(Shape::Scissors, Shape::Scissors) => Outcome::Draw,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Round {
|
||||
opponent: Shape,
|
||||
me: Shape,
|
||||
outcome: Outcome,
|
||||
}
|
||||
|
||||
impl Round {
|
||||
fn part1_from_string(s: &str) -> Option<Round> {
|
||||
let split: Vec<&str> = s.split(" ").collect();
|
||||
match (Shape::part1_from_string(split[0]), Shape::part1_from_string(split[1])) {
|
||||
(Some(opponents_shape), Some(my_shape)) => {
|
||||
Some(Round {
|
||||
opponent: opponents_shape,
|
||||
me: my_shape,
|
||||
outcome: Outcome::with_shapes(opponents_shape, my_shape)
|
||||
})
|
||||
},
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
fn part2_from_string(s: &str) -> Option<Round> {
|
||||
let split: Vec<&str> = s.split(" ").collect();
|
||||
match (Shape::part2_from_string(split[0]), Outcome::part2_from_string(split[1])) {
|
||||
(Some(opponents_shape), Some(expected_outcome)) => {
|
||||
Some(Round {
|
||||
opponent: opponents_shape,
|
||||
me: Shape::part2_from_shape_and_outcome(opponents_shape, expected_outcome),
|
||||
outcome: expected_outcome
|
||||
})
|
||||
},
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
fn score(&self) -> i32 {
|
||||
self.score_for_my_shape() + self.score_for_outcome()
|
||||
}
|
||||
|
||||
fn score_for_my_shape(&self) -> i32 {
|
||||
match self.me {
|
||||
Shape::Rock => SCORE_FOR_ROCK,
|
||||
Shape::Paper => SCORE_FOR_PAPER,
|
||||
Shape::Scissors => SCORE_FOR_SCISSORS,
|
||||
}
|
||||
}
|
||||
|
||||
fn score_for_outcome(&self) -> i32 {
|
||||
match self.outcome {
|
||||
Outcome::Win => SCORE_FOR_WIN,
|
||||
Outcome::Draw => SCORE_FOR_DRAW,
|
||||
Outcome::Loss => SCORE_FOR_LOSS,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main(input_filename: &str) -> Result<()> {
|
||||
let line_reader = line_reader_for_file(input_filename)?;
|
||||
|
||||
let mut number_of_rounds: i32 = 0;
|
||||
let mut part1_total_score: i32 = 0;
|
||||
let mut part2_total_score: i32 = 0;
|
||||
|
||||
for line in line_reader {
|
||||
let line = line.expect(format!("Failed to read line after {} rounds!", number_of_rounds).as_str());
|
||||
if let Some(round) = Round::part1_from_string(&line) {
|
||||
part1_total_score += round.score();
|
||||
}
|
||||
if let Some(round) = Round::part2_from_string(&line) {
|
||||
part2_total_score += round.score();
|
||||
}
|
||||
number_of_rounds += 1;
|
||||
}
|
||||
|
||||
println!("Processed {} rounds", number_of_rounds);
|
||||
println!("Part 1: total score two shapes: {}", part1_total_score);
|
||||
println!("Part 2: total score with expected outcomes: {}", part2_total_score);
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue