Rust Day 2

This commit is contained in:
Tobias Berger 2022-12-02 10:18:02 +01:00
parent 19559cea15
commit 747e69fbfb
Signed by: toby
GPG key ID: 2D05EFAB764D6A88
6 changed files with 2687 additions and 3 deletions

2
rust/Cargo.lock generated
View file

@ -4,4 +4,4 @@ version = 3
[[package]] [[package]]
name = "advent-of-code" name = "advent-of-code"
version = "22.1.2" version = "22.2.2"

View file

@ -1,6 +1,6 @@
[package] [package]
name = "advent-of-code" name = "advent-of-code"
version = "22.1.2" version = "22.2.2"
edition = "2021" edition = "2021"
resolver = "2" resolver = "2"
@ -29,4 +29,8 @@ path = "src/day00/main.rs"
[[bin]] [[bin]]
name = "day01" name = "day01"
path = "src/day01/main.rs" path = "src/day01/main.rs"
[[bin]]
name = "day02"
path = "src/day02/main.rs"

2500
rust/src/day02/input.txt Normal file

File diff suppressed because it is too large Load diff

161
rust/src/day02/main.rs Normal file
View file

@ -0,0 +1,161 @@
const INPUT: &str = include_str!("input.txt");
mod part_1;
use std::str::FromStr;
use part_1::part_1;
mod part_2;
use part_2::part_2;
#[derive(Clone, Copy)]
pub(crate) enum Shape {
Rock,
Paper,
Scissors,
}
#[derive(Clone, Copy)]
pub(crate) enum GameResult {
Win,
Tie,
Loss,
}
impl Shape {
fn play_against(&self, other: &Shape) -> GameResult {
match self {
Shape::Rock => match other {
Shape::Rock => GameResult::Tie,
Shape::Paper => GameResult::Loss,
Shape::Scissors => GameResult::Win,
},
Shape::Paper => match other {
Shape::Rock => GameResult::Win,
Shape::Paper => GameResult::Tie,
Shape::Scissors => GameResult::Loss,
},
Shape::Scissors => match other {
Shape::Rock => GameResult::Loss,
Shape::Paper => GameResult::Win,
Shape::Scissors => GameResult::Tie,
},
}
}
fn get_response_for_result(&self, result: &GameResult) -> Self {
match self {
Shape::Rock => match result {
GameResult::Tie => Shape::Rock,
GameResult::Loss => Shape::Scissors,
GameResult::Win => Shape::Paper,
},
Shape::Paper => match result {
GameResult::Win => Shape::Scissors,
GameResult::Tie => Shape::Paper,
GameResult::Loss => Shape::Rock,
},
Shape::Scissors => match result {
GameResult::Loss => Shape::Paper,
GameResult::Win => Shape::Rock,
GameResult::Tie => Shape::Scissors,
},
}
}
}
impl From<&Shape> for u64 {
fn from(shape: &Shape) -> Self {
match shape {
Shape::Rock => 1,
Shape::Paper => 2,
Shape::Scissors => 3,
}
}
}
impl From<&GameResult> for u64 {
fn from(game_result: &GameResult) -> Self {
match game_result {
GameResult::Win => 6,
GameResult::Tie => 3,
GameResult::Loss => 0,
}
}
}
#[derive(Debug)]
pub(crate) struct ParseShapeError;
impl FromStr for Shape {
type Err = ParseShapeError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
assert_eq!(s.len(), 1);
let Some(character) = s.bytes().next() else {
return Err(ParseShapeError);
};
match character {
b'A' | b'X' => Ok(Shape::Rock),
b'B' | b'Y' => Ok(Shape::Paper),
b'C' | b'Z' => Ok(Shape::Scissors),
_ => Err(ParseShapeError),
}
}
}
#[derive(Debug)]
pub(crate) struct ParseGameResultError;
impl FromStr for GameResult {
type Err = ParseGameResultError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
assert_eq!(s.len(), 1);
let Some(character) = s.bytes().next() else {
return Err(ParseGameResultError);
};
match character {
b'X' => Ok(GameResult::Loss),
b'Y' => Ok(GameResult::Tie),
b'Z' => Ok(GameResult::Win),
_ => Err(ParseGameResultError),
}
}
}
fn parse_input_part_1() -> Vec<[Shape; 2]> {
INPUT
.split('\n')
.map(|round_string| {
let round = round_string
.split(' ')
.map(|play| {
Shape::from_str(play).unwrap_or_else(|_| panic!("Found invalid play {play}"))
})
.take(2)
.collect::<Vec<_>>();
[round[0], round[1]]
})
.collect::<Vec<_>>()
}
fn parse_input_part_2() -> Vec<(Shape, GameResult)> {
INPUT
.split('\n')
.map(|round_string| {
let round = round_string.split(' ').take(2).collect::<Vec<_>>();
assert_eq!(round.len(), 2);
let enemy_shape = Shape::from_str(round[0])
.unwrap_or_else(|_| panic!("Found invalid play {}", round[0]));
let desired_result = GameResult::from_str(round[1])
.unwrap_or_else(|_| panic!("Found invalid desired result {}", round[1]));
(enemy_shape, desired_result)
})
.collect::<Vec<_>>()
}
pub fn main() {
part_1(parse_input_part_1().as_slice());
part_2(parse_input_part_2().as_slice());
}

8
rust/src/day02/part_1.rs Normal file
View file

@ -0,0 +1,8 @@
use crate::Shape;
pub(crate) fn part_1(input: &[[Shape; 2]]) {
let final_score = input.iter().fold(0u64, |acc, [enemy, mine]| {
acc + u64::from(&mine.play_against(enemy)) + u64::from(mine)
});
println!("Part 1: {final_score}");
}

11
rust/src/day02/part_2.rs Normal file
View file

@ -0,0 +1,11 @@
use crate::{GameResult, Shape};
pub(crate) fn part_2(input: &[(Shape, GameResult)]) {
let final_score = input
.iter()
.fold(0u64, |acc, (enemy_play, desired_result)| {
acc + u64::from(&enemy_play.get_response_for_result(desired_result))
+ u64::from(desired_result)
});
println!("Part 2: {final_score}");
}