diff --git a/source/day_02/mod.rs b/source/day_02/mod.rs new file mode 100644 index 0000000..7ce5bac --- /dev/null +++ b/source/day_02/mod.rs @@ -0,0 +1,98 @@ +use std::str::FromStr; + +use color_eyre::{ + eyre::{eyre, Error}, + Result, +}; + +pub fn solve() -> Result<()> { + let input_data = include_str!("../../data/day_02.txt").trim(); + println!("Day 02 Part 1: {}", part_1(input_data)?); + println!("Day 02 Part 2: {}", part_2(input_data)?); + Ok(()) +} + +#[derive(Debug)] +enum Command { + Forward(i32), + Down(i32), + Up(i32), +} + +impl FromStr for Command { + type Err = Error; + + fn from_str(s: &str) -> Result { + let mut split = s.split(" "); + let command = split + .next() + .ok_or(eyre!("Command not found in line: {}", s))?; + let amount = split + .next() + .ok_or(eyre!("Amount not found in line: {}", s))? + .parse()?; + + match command { + "forward" => Ok(Self::Forward(amount)), + "down" => Ok(Self::Down(amount)), + "up" => Ok(Self::Up(amount)), + _ => unimplemented!(), + } + } +} + +#[derive(Debug, Default)] +struct Submarine { + aim: i32, + depth: i32, + horizontal_position: i32, +} + +impl Submarine { + fn execute_command_1(&mut self, command: Command) { + match command { + Command::Forward(amount) => self.horizontal_position += amount, + Command::Down(amount) => self.depth += amount, + Command::Up(amount) => self.depth -= amount, + } + } + + fn execute_command_2(&mut self, command: Command) { + match command { + Command::Forward(amount) => { + self.horizontal_position += amount; + self.depth += self.aim * amount; + } + Command::Down(amount) => self.aim += amount, + Command::Up(amount) => self.aim -= amount, + } + } + + fn final_result(&self) -> i32 { + self.horizontal_position * self.depth + } +} + +fn parse_commands(input: &str) -> Result> { + input.lines().map(Command::from_str).collect::>() +} + +fn part_1(input: &str) -> Result { + let mut submarine = Submarine::default(); + + parse_commands(input)? + .into_iter() + .for_each(|command| submarine.execute_command_1(command)); + + Ok(submarine.final_result()) +} + +fn part_2(input: &str) -> Result { + let mut submarine = Submarine::default(); + + parse_commands(input)? + .into_iter() + .for_each(|command| submarine.execute_command_2(command)); + + Ok(submarine.final_result()) +} diff --git a/source/main.rs b/source/main.rs index 8d42540..6313b77 100644 --- a/source/main.rs +++ b/source/main.rs @@ -1,10 +1,12 @@ mod day_01; +mod day_02; fn main() -> color_eyre::Result<()> { color_eyre::install()?; println!("Advent of Code 2021"); day_01::solve()?; + day_02::solve()?; Ok(()) }