use aoc_runner_derive::{aoc, aoc_generator}; use strum_macros::Display; #[derive(Debug, PartialEq, Eq, Clone)] struct Step { dir: Direction, length: i32 } #[derive(Debug, Display, PartialEq, Eq, Clone, Copy)] enum Direction { Up, Down, Left, Right } impl Direction { fn get_coordinate_modifier(&self) -> (i32, i32) { match self { Direction::Up => (0, 1), Direction::Down => (0, -1), Direction::Left => (-1, 0), Direction::Right => (1, 0), } } } trait DirectionConvertable { fn to_direction(&self) -> Direction; } impl DirectionConvertable for &str { fn to_direction(&self) -> Direction { match *self { "U" => Direction::Up, "D" => Direction::Down, "L" => Direction::Left, "R" => Direction::Right, _ => panic!("Invalid Direction") } } } #[aoc_generator(day18)] fn parse(input: &str) -> Vec { let steps = input.lines() .map(|line| { let mut line = line.split(' '); Step { dir: line.next().unwrap().to_direction(), length: line.next().unwrap().parse::().unwrap(), } }).collect::>(); steps } #[aoc(day18, part1)] fn part1(steps: &Vec) -> i32 { let verticies = get_verticies(steps); let mut area = 0; for win in verticies.windows(2) { area += win[0].y * win[1].x; area -= win[0].x * win[1].y; } // Due to how area works in math, half of the premitier spots are included in the area calculation. (area / 2) + (verticies.len() as i32 / 2) + 1 } #[derive(Debug, PartialEq, Eq, Clone)] struct Coordinate { x: i32, y: i32 } fn get_verticies(steps: &Vec) -> Vec { let mut cur_pos = Coordinate{ x: 0, y: 0 }; let mut verticies: Vec = vec![cur_pos.clone()]; for step in steps { let (x_mod, y_mod) = step.dir.get_coordinate_modifier(); for _ in 0..step.length { let new_pos = Coordinate{ x: cur_pos.x + x_mod, y: cur_pos.y + y_mod, }; cur_pos = new_pos.clone(); verticies.push(new_pos.clone()); } } verticies } // #[aoc(day18, part2)] // fn part2(steps: &Vec) -> i32 { // todo!() // } #[cfg(test)] mod tests { use super::*; const EX: &str = r"R 6 (#70c710) D 5 (#0dc571) L 2 (#5713f0) D 2 (#d2c081) R 2 (#59c680) D 2 (#411b91) L 5 (#8ceee2) U 2 (#caa173) L 1 (#1b58a2) U 2 (#caa171) R 2 (#7807d2) U 3 (#a77fa3) L 2 (#015232) U 2 (#7a21e3)"; const EX_2: &str = r"R 6 (#70c710) D 6 (#0dc571) L 6 (#5713f0) U 6 (#d2c081)"; #[test] fn part1_example() { assert_eq!(part1(&parse(EX)), 62); } #[test] fn part1_example2() { assert_eq!(part1(&parse(EX_2)), 49); } // #[test] // fn part2_example() { // assert_eq!(part2(&parse(EX)), ""); // } }