AoC2021/src/day02.rs

88 lines
2.1 KiB
Rust

use crate::Day;
use anyhow::Result;
pub struct Day02(Vec<Instruction>);
enum Instruction {
Forward(i32),
Down(i32),
Up(i32),
}
impl Day for Day02 {
fn init(content: String) -> Result<Self> {
let lines = content.lines().map(str_to_instr).collect::<Result<Vec<Instruction>>>()?;
Ok(Self(lines))
}
fn part1(&self) -> Result<String> {
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<String> {
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<Instruction> {
let v = s.split(' ').collect::<Vec<&str>>();
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");
}