Use a binary heap for day8

This commit is contained in:
traxys 2025-12-08 14:53:04 +01:00
parent aade7c356e
commit 6f3f655eb7

View file

@ -1,4 +1,4 @@
use std::time::Instant;
use std::{collections::BinaryHeap, time::Instant};
use aoc_2025::{load, print_res};
use bstr::BString;
@ -144,16 +144,55 @@ pub fn part1(input: Parsed) {
#[inline(never)]
pub fn part2(input: Parsed) {
let mut pairs: Vec<_> = (0..input.len())
.flat_map(|ia| ((ia + 1)..input.len()).map(move |ib| (ia, ib)))
struct PointPair<'a> {
a: &'a Point3,
b: &'a Point3,
ia: usize,
ib: usize,
dist2: u64,
}
impl<'a> Eq for PointPair<'a> {}
impl<'a> PartialEq for PointPair<'a> {
fn eq(&self, other: &Self) -> bool {
self.dist2.eq(&other.dist2)
}
}
impl<'a> PartialOrd for PointPair<'a> {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl<'a> Ord for PointPair<'a> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.dist2.cmp(&other.dist2)
}
}
let pp = |ia, ib| {
let a = &input[ia];
let b = &input[ib];
PointPair {
a,
ia,
b,
ib,
dist2: a.dist2(b),
}
};
let pairs: BinaryHeap<_> = (0..input.len())
.flat_map(|ia| ((ia + 1)..input.len()).map(move |ib| pp(ia, ib)))
.collect();
pairs.sort_unstable_by_key(|&(ia, ib)| input[ia].dist2(&input[ib]));
let mut uf = UnionFind::new(input.len());
for &(ia, ib) in &pairs {
for &PointPair { ia, ib, a, b, .. } in pairs.iter() {
uf.union(ia as u16, ib as u16);
if uf.set_count() == 1 {
print_res!("X product of last boxes: {}", input[ia].x * input[ib].x);
print_res!("X product of last boxes: {}", a.x * b.x);
return;
}
}