Compare commits
2 commits
a8ee7f78f6
...
c9bd84ebdb
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c9bd84ebdb | ||
|
|
172b33b63c |
3 changed files with 30 additions and 25 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
|
@ -76,6 +76,7 @@ dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"color-eyre",
|
"color-eyre",
|
||||||
"humantime",
|
"humantime",
|
||||||
|
"rustc-hash",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -319,6 +320,12 @@ version = "0.1.26"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
|
checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-hash"
|
||||||
|
version = "2.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.228"
|
version = "1.0.228"
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ bstr = "1.11.0"
|
||||||
clap = { version = "4.5.21", features = ["derive"] }
|
clap = { version = "4.5.21", features = ["derive"] }
|
||||||
color-eyre = "0.6.3"
|
color-eyre = "0.6.3"
|
||||||
humantime = "2.1.0"
|
humantime = "2.1.0"
|
||||||
|
rustc-hash = "2.1.1"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
debug = true
|
debug = true
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,14 @@
|
||||||
use std::{
|
use std::{collections::HashSet, hash::Hash, ops::RangeInclusive, time::Instant};
|
||||||
collections::{HashMap, HashSet},
|
|
||||||
hash::Hash,
|
use rustc_hash::FxHashMap;
|
||||||
ops::RangeInclusive,
|
|
||||||
time::Instant,
|
|
||||||
};
|
|
||||||
|
|
||||||
use aoc_2025::{load, print_res};
|
use aoc_2025::{load, print_res};
|
||||||
use bstr::BString;
|
use bstr::BString;
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
|
#[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
|
||||||
pub struct Point2 {
|
pub struct Point2 {
|
||||||
x: u64,
|
x: u32,
|
||||||
y: u64,
|
y: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
type Parsed = Vec<Point2>;
|
type Parsed = Vec<Point2>;
|
||||||
|
|
@ -32,7 +29,7 @@ pub fn parsing(input: &BString) -> color_eyre::Result<Parsed> {
|
||||||
.collect()
|
.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)
|
(a.x.abs_diff(b.x) + 1) * (a.y.abs_diff(b.y) + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,11 +49,11 @@ pub fn part1(input: Parsed) {
|
||||||
struct Polygon {
|
struct Polygon {
|
||||||
points: Vec<Point2>,
|
points: Vec<Point2>,
|
||||||
|
|
||||||
x_values: Vec<u64>,
|
x_values: Vec<u32>,
|
||||||
y_values: Vec<u64>,
|
y_values: Vec<u32>,
|
||||||
|
|
||||||
vertical_edges_by_x_slot: Vec<Vec<RangeInclusive<u64>>>,
|
vertical_edges_by_x_slot: Vec<Vec<RangeInclusive<u32>>>,
|
||||||
horizontal_edges_by_y_slot: Vec<Vec<RangeInclusive<u64>>>,
|
horizontal_edges_by_y_slot: Vec<Vec<RangeInclusive<u32>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Polygon {
|
impl Polygon {
|
||||||
|
|
@ -167,11 +164,11 @@ impl Polygon {
|
||||||
&self.points
|
&self.points
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn x_values(&self) -> &[u64] {
|
pub fn x_values(&self) -> &[u32] {
|
||||||
&self.x_values
|
&self.x_values
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn y_values(&self) -> &[u64] {
|
pub fn y_values(&self) -> &[u32] {
|
||||||
&self.y_values
|
&self.y_values
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -184,7 +181,7 @@ impl Polygon {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct InsertGuard<'a, K, V>(K, V, &'a mut HashMap<K, V>)
|
struct InsertGuard<'a, K, V>(K, V, &'a mut FxHashMap<K, V>)
|
||||||
where
|
where
|
||||||
K: Hash + Eq + Copy,
|
K: Hash + Eq + Copy,
|
||||||
V: Copy;
|
V: Copy;
|
||||||
|
|
@ -203,15 +200,15 @@ fn horizontal_edges_contained(
|
||||||
poly: &Polygon,
|
poly: &Polygon,
|
||||||
a: Point2,
|
a: Point2,
|
||||||
b: Point2,
|
b: Point2,
|
||||||
cache: &mut HashMap<Point2, bool>,
|
cache: &mut FxHashMap<Point2, bool>,
|
||||||
edge_cache: &mut HashMap<(u64, (u64, u64)), bool>,
|
edge_cache: &mut FxHashMap<(u32, (u32, u32)), bool>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
assert_ne!(a.x, b.x);
|
assert_ne!(a.x, b.x);
|
||||||
|
|
||||||
let min_x = a.x.min(b.x);
|
let min_x = a.x.min(b.x);
|
||||||
let max_x = a.x.max(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) {
|
let mut contains = |point: Point2| match cache.get(&point) {
|
||||||
Some(&v) => v,
|
Some(&v) => v,
|
||||||
|
|
@ -277,15 +274,15 @@ fn vertical_edges_contain(
|
||||||
poly: &Polygon,
|
poly: &Polygon,
|
||||||
a: Point2,
|
a: Point2,
|
||||||
b: Point2,
|
b: Point2,
|
||||||
cache: &mut HashMap<Point2, bool>,
|
cache: &mut FxHashMap<Point2, bool>,
|
||||||
edge_cache: &mut HashMap<(u64, (u64, u64)), bool>,
|
edge_cache: &mut FxHashMap<(u32, (u32, u32)), bool>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
assert_ne!(a.y, b.y);
|
assert_ne!(a.y, b.y);
|
||||||
|
|
||||||
let min_y = a.y.min(b.y);
|
let min_y = a.y.min(b.y);
|
||||||
let max_y = a.y.max(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) {
|
let mut contains = |point: Point2| match cache.get(&point) {
|
||||||
Some(&v) => v,
|
Some(&v) => v,
|
||||||
|
|
@ -353,9 +350,9 @@ pub fn part2(input: Parsed) {
|
||||||
|
|
||||||
let mut max_area = 0;
|
let mut max_area = 0;
|
||||||
|
|
||||||
let mut contains_cache = HashMap::new();
|
let mut contains_cache = FxHashMap::default();
|
||||||
let mut h_edge_cache = HashMap::new();
|
let mut h_edge_cache = FxHashMap::default();
|
||||||
let mut v_edge_cache = HashMap::new();
|
let mut v_edge_cache = FxHashMap::default();
|
||||||
|
|
||||||
for (ia, &a) in poly.points().iter().enumerate() {
|
for (ia, &a) in poly.points().iter().enumerate() {
|
||||||
for &b in poly.points().iter().skip(ia + 1) {
|
for &b in poly.points().iter().skip(ia + 1) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue