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.rs | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 2021/src/bin/day_2.rs (limited to '2021/src/bin/day_2.rs') diff --git a/2021/src/bin/day_2.rs b/2021/src/bin/day_2.rs new file mode 100644 index 0000000..08d01c3 --- /dev/null +++ b/2021/src/bin/day_2.rs @@ -0,0 +1,100 @@ +use nom::{ + branch::alt, + bytes::complete::tag, + character::complete::{i64 as nom_i64, line_ending, space1}, + combinator::{map, value}, + 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)] +struct Instruction { + direction: Direction, + distance: Distance, +} + +#[derive(Debug, Clone)] +enum Direction { + Forward, + Up, + Down, +} +#[derive( + Default, + Debug, + Clone, + Copy, + derive_more::Add, + derive_more::AddAssign, + derive_more::Sub, + derive_more::SubAssign, +)] +struct Distance(i64); + +#[derive(Default, Debug)] +struct Position { + horizontal: Distance, + depth: Distance, +} + +impl Position { + fn advance(&mut self, instruction: &Instruction) { + match instruction.direction { + Direction::Forward => self.horizontal += instruction.distance, + Direction::Down => self.depth += instruction.distance, + Direction::Up => self.depth -= instruction.distance, + } + } +} + +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> { + map( + tuple((parse_direction, space1, parse_distance)), + |(direction, _, distance)| Instruction { + direction, + distance, + }, + )(input) +} + +fn parse_direction(input: &str) -> IResult<&str, Direction> { + alt(( + value(Direction::Forward, tag("forward")), + value(Direction::Up, tag("up")), + value(Direction::Down, tag("down")), + ))(input) +} + +fn parse_distance(input: &str) -> IResult<&str, Distance> { + map(nom_i64, Distance)(input) +} -- cgit v1.2.3