From 6d72191e2ce5d423ca03c894d2dad1d3061bd4f3 Mon Sep 17 00:00:00 2001 From: Justin Wernick Date: Tue, 19 Apr 2022 20:27:29 +0200 Subject: Refile for merging repos --- 2021/src/bin/day_2_part_2.rs | 124 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 2021/src/bin/day_2_part_2.rs (limited to '2021/src/bin/day_2_part_2.rs') diff --git a/2021/src/bin/day_2_part_2.rs b/2021/src/bin/day_2_part_2.rs new file mode 100644 index 0000000..de5b334 --- /dev/null +++ b/2021/src/bin/day_2_part_2.rs @@ -0,0 +1,124 @@ +use nom::{ + branch::alt, + bytes::complete::tag, + character::complete::{i64 as nom_i64, line_ending, space1}, + combinator::map, + multi::separated_list1, + sequence::tuple, + IResult, +}; +use std::fs; + +fn main() -> Result<(), Box> { + let input = fs::read_to_string("inputs/day_2.txt")?; + let route = parse_route(&input).unwrap().1; + + let mut position = Position::default(); + for instruction in &route { + position.advance(&instruction); + } + dbg!(position.horizontal.0 * position.depth.0); + + Ok(()) +} + +#[derive(Debug)] +struct Route(Vec); + +impl<'a> IntoIterator for &'a Route { + type Item = &'a Instruction; + type IntoIter = std::slice::Iter<'a, Instruction>; + fn into_iter(self) -> ::IntoIter { + self.0.iter() + } +} + +#[derive(Debug)] +enum Instruction { + Forward(Distance), + Up(Aim), + Down(Aim), +} + +#[derive( + Default, + Debug, + Clone, + Copy, + derive_more::Add, + derive_more::AddAssign, + derive_more::Sub, + derive_more::SubAssign, +)] +struct Distance(i64); +#[derive( + Default, + Debug, + Clone, + Copy, + derive_more::Add, + derive_more::AddAssign, + derive_more::Sub, + derive_more::SubAssign, +)] +struct Aim(i64); + +impl std::ops::Mul for Aim { + type Output = Distance; + fn mul(self, other: Distance) -> Distance { + Distance(self.0 * other.0) + } +} + +#[derive(Default, Debug)] +struct Position { + horizontal: Distance, + depth: Distance, + aim: Aim, +} + +impl Position { + fn advance(&mut self, instruction: &Instruction) { + match instruction { + Instruction::Forward(distance) => { + self.horizontal += *distance; + self.depth += self.aim * *distance; + } + Instruction::Down(aim) => self.aim += *aim, + Instruction::Up(aim) => self.aim -= *aim, + } + } +} + +fn parse_route(input: &str) -> IResult<&str, Route> { + map(separated_list1(line_ending, parse_instruction), Route)(input) +} + +fn parse_instruction(input: &str) -> IResult<&str, Instruction> { + alt((parse_forward, parse_up, parse_down))(input) +} + +fn parse_forward(input: &str) -> IResult<&str, Instruction> { + map( + tuple((tag("forward"), space1, parse_distance)), + |(_, _, distance)| Instruction::Forward(distance), + )(input) +} +fn parse_up(input: &str) -> IResult<&str, Instruction> { + map(tuple((tag("up"), space1, parse_aim)), |(_, _, aim)| { + Instruction::Up(aim) + })(input) +} +fn parse_down(input: &str) -> IResult<&str, Instruction> { + map(tuple((tag("down"), space1, parse_aim)), |(_, _, aim)| { + Instruction::Down(aim) + })(input) +} + +fn parse_distance(input: &str) -> IResult<&str, Distance> { + map(nom_i64, Distance)(input) +} + +fn parse_aim(input: &str) -> IResult<&str, Aim> { + map(nom_i64, Aim)(input) +} -- cgit v1.2.3