summaryrefslogtreecommitdiff
path: root/2021/src/bin/day_2.rs
diff options
context:
space:
mode:
Diffstat (limited to '2021/src/bin/day_2.rs')
-rw-r--r--2021/src/bin/day_2.rs100
1 files changed, 100 insertions, 0 deletions
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<dyn std::error::Error>> {
+ 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<Instruction>);
+
+impl<'a> IntoIterator for &'a Route {
+ type Item = &'a Instruction;
+ type IntoIter = std::slice::Iter<'a, Instruction>;
+ fn into_iter(self) -> <Self as IntoIterator>::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)
+}