use crate::Day; use anyhow::Result; pub struct Day02(Vec); enum Instruction { Forward(i32), Down(i32), Up(i32), } impl Day for Day02 { fn init(content: String) -> Result { let lines = content.lines().map(str_to_instr).collect::>>()?; Ok(Self(lines)) } fn part1(&self) -> Result { let mut depth = 0; let mut fw = 0; for i in &self.0 { match i { Instruction::Forward(n) => fw += n, Instruction::Down(n) => depth += n, Instruction::Up(n) => depth -= n, } } Ok(format!("{}", depth * fw)) } fn part2(&self) -> Result { let mut depth = 0; let mut fw = 0; let mut aim = 0; for i in &self.0 { match i { Instruction::Forward(n) => { fw += n; depth += aim * n; } Instruction::Down(n) => aim += n, Instruction::Up(n) => aim -= n, } } Ok(format!("{}", depth * fw)) } } fn str_to_instr(s: &str) -> Result { let v = s.split(' ').collect::>(); let name = v[0]; let height = v[1].parse()?; match name { "forward" => Ok(Instruction::Forward(height)), "up" => Ok(Instruction::Up(height)), "down" => Ok(Instruction::Down(height)), _ => Err(anyhow::Error::msg("This is not a valid direction!")) } } #[cfg(test)] mod tests { use crate::day02::Day02; use crate::day::Day; use crate::day_tests; use super::Result; const D: &str = r"forward 5 down 5 forward 8 up 3 down 8 forward 2"; #[test] fn part1_test() -> Result<()> { let d2 = Day02::init(String::from(D))?; Ok(assert_eq!("150", d2.part1()?)) } #[test] fn part2_test() -> Result<()> { let d2 = Day02::init(String::from(D))?; Ok(assert_eq!("900", d2.part2()?)) } day_tests!(Day02, "02", "1524750", "1592426537"); }