diff options
Diffstat (limited to '2023/src/bin/day_18.rs')
-rw-r--r-- | 2023/src/bin/day_18.rs | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/2023/src/bin/day_18.rs b/2023/src/bin/day_18.rs index c3e9f58..a4c9355 100644 --- a/2023/src/bin/day_18.rs +++ b/2023/src/bin/day_18.rs @@ -16,9 +16,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { let mut fill_map = parsed.draw_map(); fill_map.derive_inside_outside(); dbg!(&fill_map.count_inside()); + dbg!(&parsed.find_internal_area()); let hex_parsed = Instructions::hex_parser(&input).unwrap().1; - dbg!(&hex_parsed); + dbg!(&hex_parsed.find_internal_area()); + Ok(()) } @@ -27,15 +29,15 @@ struct Instructions(Vec<Instruction>); #[derive(Debug)] struct Instruction { - direction: Vector2<i32>, + direction: Vector2<i64>, distance: u32, } #[derive(Debug)] struct FloodFillMap { - map: HashMap<Point2<i32>, Fill>, - top_left: Point2<i32>, - bottom_right: Point2<i32>, + map: HashMap<Point2<i64>, Fill>, + top_left: Point2<i64>, + bottom_right: Point2<i64>, } #[derive(Debug, PartialEq, Eq, Clone, Copy)] @@ -71,6 +73,31 @@ impl Instructions { FloodFillMap::new(trench) } + + fn find_internal_area(&self) -> i64 { + let mut current_point = Point2::new(0, 0); + let mut points = vec![current_point]; + + let mut perimeter = 0; + for instruction in &self.0 { + let next_point = current_point + instruction.direction * instruction.distance as i64; + points.push(next_point); + current_point = next_point; + perimeter += instruction.distance as i64; + } + + let mut area = 0; + for point in points.windows(2) { + if let &[p1, p2] = point { + area += p1.x * p2.y; + area -= p1.y * p2.x; + } else { + unreachable!() + } + } + + (perimeter + 2 + area) / 2 + } } impl Instruction { @@ -112,7 +139,7 @@ impl Instruction { } } -fn dir_parser(input: &str) -> IResult<&str, Vector2<i32>> { +fn dir_parser(input: &str) -> IResult<&str, Vector2<i64>> { alt(( value(Vector2::new(0, -1), char('U')), value(Vector2::new(0, 1), char('D')), @@ -121,7 +148,7 @@ fn dir_parser(input: &str) -> IResult<&str, Vector2<i32>> { ))(input) } -fn hex_dir_parser(input: &str) -> IResult<&str, Vector2<i32>> { +fn hex_dir_parser(input: &str) -> IResult<&str, Vector2<i64>> { alt(( value(Vector2::new(0, -1), char('3')), value(Vector2::new(0, 1), char('1')), @@ -131,7 +158,7 @@ fn hex_dir_parser(input: &str) -> IResult<&str, Vector2<i32>> { } impl FloodFillMap { - fn new(map: HashMap<Point2<i32>, Fill>) -> FloodFillMap { + fn new(map: HashMap<Point2<i64>, Fill>) -> FloodFillMap { let top_left = Point2::new( map.keys().map(|key| key.x).min().unwrap() - 1, map.keys().map(|key| key.y).min().unwrap() - 1, @@ -166,7 +193,7 @@ impl FloodFillMap { .count() } - fn flood_fill(&mut self, start: Point2<i32>, fill: &Fill) { + fn flood_fill(&mut self, start: Point2<i64>, fill: &Fill) { let mut to_fill = vec![start]; while let Some(next) = to_fill.pop() { |