From 6f3f655eb7f0390d8b75170226bf7b8d0178df2b Mon Sep 17 00:00:00 2001 From: traxys Date: Mon, 8 Dec 2025 14:53:04 +0100 Subject: [PATCH] Use a binary heap for day8 --- src/bin/day8.rs | 51 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/src/bin/day8.rs b/src/bin/day8.rs index ab31427..e8eea5e 100644 --- a/src/bin/day8.rs +++ b/src/bin/day8.rs @@ -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 { + 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; } }