use std::str::FromStr; use color_eyre::eyre; use eyre::{eyre, ensure}; use crate::lib::ParseLines; enum Direction { Forward, Up, Down, } struct MoveCmd { dir: Direction, value: i32, } impl<'a> FromStr for MoveCmd { type Err = eyre::Report; fn from_str(s: &str) -> Result { let parts: Vec<&str> = s.split_whitespace().collect(); ensure!(parts.len() == 2, "Could not parse: \"{}\" (Wrong number of words)", s); let dir = match parts[0] { "forward" => Direction::Forward, "up" => Direction::Up, "down" => Direction::Down, _ => return Err(eyre!("Could not parse: \"{}\" (invalid axis)", s)), }; let value = parts[1].parse::()?; Ok(MoveCmd{dir, value}) } } pub fn part1(data: &str) -> eyre::Result<()> { let mut horiz = 0; // how many units forward let mut vert = 0; // how many units DOWN (so flipped) for res in data.parse_lines::() { let cmd = res?; match cmd.dir { Direction::Forward => horiz += cmd.value, Direction::Up => vert -= cmd.value, Direction::Down => vert += cmd.value, } } println!("One: {}", horiz * vert); Ok(()) } pub fn part2(data: &str) -> eyre::Result<()> { let mut horiz = 0; let mut vert = 0; let mut aim = 0; for res in data.parse_lines::() { let cmd = res?; match cmd.dir { Direction::Down => aim += cmd.value, // flipped again Direction::Up => aim -= cmd.value, Direction::Forward => { horiz += cmd.value; vert += cmd.value * aim; } } } println!("Two: {}", horiz * vert); Ok(()) }