88 lines
2.1 KiB
Rust
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");
|
|
} |