From 172b33b63c88abc27deb5e987321f980c85e8fe0 Mon Sep 17 00:00:00 2001 From: Quentin Boyer Date: Wed, 10 Dec 2025 01:37:13 +0100 Subject: [PATCH 1/2] Switch to u32 to reduce the hash complexity --- src/bin/day9.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/bin/day9.rs b/src/bin/day9.rs index 8c4af39..b79d146 100644 --- a/src/bin/day9.rs +++ b/src/bin/day9.rs @@ -10,8 +10,8 @@ use bstr::BString; #[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)] pub struct Point2 { - x: u64, - y: u64, + x: u32, + y: u32, } type Parsed = Vec; @@ -32,7 +32,7 @@ pub fn parsing(input: &BString) -> color_eyre::Result { .collect() } -fn rect_area(a: &Point2, b: &Point2) -> u64 { +fn rect_area(a: &Point2, b: &Point2) -> u32 { (a.x.abs_diff(b.x) + 1) * (a.y.abs_diff(b.y) + 1) } @@ -52,11 +52,11 @@ pub fn part1(input: Parsed) { struct Polygon { points: Vec, - x_values: Vec, - y_values: Vec, + x_values: Vec, + y_values: Vec, - vertical_edges_by_x_slot: Vec>>, - horizontal_edges_by_y_slot: Vec>>, + vertical_edges_by_x_slot: Vec>>, + horizontal_edges_by_y_slot: Vec>>, } impl Polygon { @@ -167,11 +167,11 @@ impl Polygon { &self.points } - pub fn x_values(&self) -> &[u64] { + pub fn x_values(&self) -> &[u32] { &self.x_values } - pub fn y_values(&self) -> &[u64] { + pub fn y_values(&self) -> &[u32] { &self.y_values } @@ -204,14 +204,14 @@ fn horizontal_edges_contained( a: Point2, b: Point2, cache: &mut HashMap, - edge_cache: &mut HashMap<(u64, (u64, u64)), bool>, + edge_cache: &mut HashMap<(u32, (u32, u32)), bool>, ) -> bool { assert_ne!(a.x, b.x); let min_x = a.x.min(b.x); let max_x = a.x.max(b.x); - let y_values: &[u64] = if a.y == b.y { &[a.y] } else { &[a.y, b.y] }; + let y_values: &[u32] = if a.y == b.y { &[a.y] } else { &[a.y, b.y] }; let mut contains = |point: Point2| match cache.get(&point) { Some(&v) => v, @@ -278,14 +278,14 @@ fn vertical_edges_contain( a: Point2, b: Point2, cache: &mut HashMap, - edge_cache: &mut HashMap<(u64, (u64, u64)), bool>, + edge_cache: &mut HashMap<(u32, (u32, u32)), bool>, ) -> bool { assert_ne!(a.y, b.y); let min_y = a.y.min(b.y); let max_y = a.y.max(b.y); - let x_values: &[u64] = if a.x == b.x { &[a.x] } else { &[a.x, b.x] }; + let x_values: &[u32] = if a.x == b.x { &[a.x] } else { &[a.x, b.x] }; let mut contains = |point: Point2| match cache.get(&point) { Some(&v) => v, From c9bd84ebdb0bc22a134e0a5f56bedcf98e97dfd1 Mon Sep 17 00:00:00 2001 From: Quentin Boyer Date: Wed, 10 Dec 2025 01:39:56 +0100 Subject: [PATCH 2/2] =?UTF-8?q?Use=20FX=E2=80=AFHash?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + src/bin/day9.rs | 25 +++++++++++-------------- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 84b4c38..5395d3c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -76,6 +76,7 @@ dependencies = [ "clap", "color-eyre", "humantime", + "rustc-hash", ] [[package]] @@ -319,6 +320,12 @@ version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + [[package]] name = "serde" version = "1.0.228" diff --git a/Cargo.toml b/Cargo.toml index 0e89dad..962f7e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ bstr = "1.11.0" clap = { version = "4.5.21", features = ["derive"] } color-eyre = "0.6.3" humantime = "2.1.0" +rustc-hash = "2.1.1" [profile.release] debug = true diff --git a/src/bin/day9.rs b/src/bin/day9.rs index b79d146..7396fe9 100644 --- a/src/bin/day9.rs +++ b/src/bin/day9.rs @@ -1,9 +1,6 @@ -use std::{ - collections::{HashMap, HashSet}, - hash::Hash, - ops::RangeInclusive, - time::Instant, -}; +use std::{collections::HashSet, hash::Hash, ops::RangeInclusive, time::Instant}; + +use rustc_hash::FxHashMap; use aoc_2025::{load, print_res}; use bstr::BString; @@ -184,7 +181,7 @@ impl Polygon { } } -struct InsertGuard<'a, K, V>(K, V, &'a mut HashMap) +struct InsertGuard<'a, K, V>(K, V, &'a mut FxHashMap) where K: Hash + Eq + Copy, V: Copy; @@ -203,8 +200,8 @@ fn horizontal_edges_contained( poly: &Polygon, a: Point2, b: Point2, - cache: &mut HashMap, - edge_cache: &mut HashMap<(u32, (u32, u32)), bool>, + cache: &mut FxHashMap, + edge_cache: &mut FxHashMap<(u32, (u32, u32)), bool>, ) -> bool { assert_ne!(a.x, b.x); @@ -277,8 +274,8 @@ fn vertical_edges_contain( poly: &Polygon, a: Point2, b: Point2, - cache: &mut HashMap, - edge_cache: &mut HashMap<(u32, (u32, u32)), bool>, + cache: &mut FxHashMap, + edge_cache: &mut FxHashMap<(u32, (u32, u32)), bool>, ) -> bool { assert_ne!(a.y, b.y); @@ -353,9 +350,9 @@ 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(); + let mut contains_cache = FxHashMap::default(); + let mut h_edge_cache = FxHashMap::default(); + let mut v_edge_cache = FxHashMap::default(); for (ia, &a) in poly.points().iter().enumerate() { for &b in poly.points().iter().skip(ia + 1) {