diff --git a/src/bin/day9.rs b/src/bin/day9.rs index 8c4af39..f30a8e7 100644 --- a/src/bin/day9.rs +++ b/src/bin/day9.rs @@ -1,9 +1,4 @@ -use std::{ - collections::{HashMap, HashSet}, - hash::Hash, - ops::RangeInclusive, - time::Instant, -}; +use std::{collections::HashSet, ops::RangeInclusive, time::Instant}; use aoc_2025::{load, print_res}; use bstr::BString; @@ -184,28 +179,7 @@ impl Polygon { } } -struct InsertGuard<'a, K, V>(K, V, &'a mut HashMap) -where - K: Hash + Eq + Copy, - V: Copy; - -impl<'a, K, V> Drop for InsertGuard<'a, K, V> -where - K: Hash + Eq + Copy, - V: Copy, -{ - fn drop(&mut self) { - self.2.insert(self.0, self.1); - } -} - -fn horizontal_edges_contained( - poly: &Polygon, - a: Point2, - b: Point2, - cache: &mut HashMap, - edge_cache: &mut HashMap<(u64, (u64, u64)), bool>, -) -> bool { +fn horizontal_edges_contained(poly: &Polygon, a: Point2, b: Point2) -> bool { assert_ne!(a.x, b.x); let min_x = a.x.min(b.x); @@ -213,30 +187,14 @@ fn horizontal_edges_contained( let y_values: &[u64] = if a.y == b.y { &[a.y] } else { &[a.y, b.y] }; - let mut contains = |point: Point2| match cache.get(&point) { - Some(&v) => v, - None => { - let v = poly.contains(point); - cache.insert(point, v); - v - } - }; - for &y in y_values { - let key = (y, (min_x, max_x)); - if let Some(&v) = edge_cache.get(&key) { - return v; - } - - let guard = InsertGuard(key, false, edge_cache); - // Left corner - if !contains(Point2 { x: min_x, y }) { + if !poly.contains(Point2 { x: min_x, y }) { return false; } - if !contains(Point2 { x: min_x + 1, y }) { + if !poly.contains(Point2 { x: min_x + 1, y }) { return false; } @@ -248,9 +206,9 @@ fn horizontal_edges_contained( .skip_while(|&&x| x <= min_x) .take_while(|&&x| x < max_x) { - if !contains(Point2 { x, y }) - || !contains(Point2 { x: x - 1, y }) - || !contains(Point2 { x: x + 1, y }) + if !poly.contains(Point2 { x, y }) + || !poly.contains(Point2 { x: x - 1, y }) + || !poly.contains(Point2 { x: x + 1, y }) { return false; } @@ -258,28 +216,19 @@ fn horizontal_edges_contained( // Right corner - if !contains(Point2 { x: max_x, y }) { + if !poly.contains(Point2 { x: max_x, y }) { return false; } - if !contains(Point2 { x: max_x - 1, y }) { + if !poly.contains(Point2 { x: max_x - 1, y }) { return false; } - - std::mem::forget(guard); - edge_cache.insert(key, true); } true } -fn vertical_edges_contain( - poly: &Polygon, - a: Point2, - b: Point2, - cache: &mut HashMap, - edge_cache: &mut HashMap<(u64, (u64, u64)), bool>, -) -> bool { +fn vertical_edges_contain(poly: &Polygon, a: Point2, b: Point2) -> bool { assert_ne!(a.y, b.y); let min_y = a.y.min(b.y); @@ -287,30 +236,14 @@ fn vertical_edges_contain( let x_values: &[u64] = if a.x == b.x { &[a.x] } else { &[a.x, b.x] }; - let mut contains = |point: Point2| match cache.get(&point) { - Some(&v) => v, - None => { - let v = poly.contains(point); - cache.insert(point, v); - v - } - }; - for &x in x_values { - let key = (x, (min_y, max_y)); - if let Some(&v) = edge_cache.get(&key) { - return v; - } - - let guard = InsertGuard(key, false, edge_cache); - // Bottom corner - if !contains(Point2 { x, y: min_y }) { + if !poly.contains(Point2 { x, y: min_y }) { return false; } - if !contains(Point2 { x, y: min_y + 1 }) { + if !poly.contains(Point2 { x, y: min_y + 1 }) { return false; } @@ -322,9 +255,9 @@ fn vertical_edges_contain( .skip_while(|&&y| y <= min_y) .take_while(|&&y| y < max_y) { - if !contains(Point2 { x, y }) - || !contains(Point2 { x, y: y - 1 }) - || !contains(Point2 { x, y: y + 1 }) + if !poly.contains(Point2 { x, y }) + || !poly.contains(Point2 { x, y: y - 1 }) + || !poly.contains(Point2 { x, y: y + 1 }) { return false; } @@ -332,16 +265,13 @@ fn vertical_edges_contain( // Top corner - if !contains(Point2 { x, y: max_y }) { + if !poly.contains(Point2 { x, y: max_y }) { return false; } - if !contains(Point2 { x, y: max_y - 1 }) { + if !poly.contains(Point2 { x, y: max_y - 1 }) { return false; } - - std::mem::forget(guard); - edge_cache.insert(key, true); } true @@ -353,10 +283,6 @@ pub fn part2(input: Parsed) { let mut max_area = 0; - let mut contains_cache = HashMap::new(); - let mut h_edge_cache = HashMap::new(); - let mut v_edge_cache = HashMap::new(); - for (ia, &a) in poly.points().iter().enumerate() { for &b in poly.points().iter().skip(ia + 1) { let area = rect_area(&a, &b); @@ -367,15 +293,11 @@ pub fn part2(input: Parsed) { assert!(area > 1); - if a.x != b.x - && !horizontal_edges_contained(&poly, a, b, &mut contains_cache, &mut h_edge_cache) - { + if a.x != b.x && !horizontal_edges_contained(&poly, a, b) { continue; } - if a.y != b.y - && !vertical_edges_contain(&poly, a, b, &mut contains_cache, &mut v_edge_cache) - { + if a.y != b.y && !vertical_edges_contain(&poly, a, b) { continue; }