diff --git a/2025/08/p2.rs b/2025/08/p2.rs new file mode 100644 index 0000000..25190a0 --- /dev/null +++ b/2025/08/p2.rs @@ -0,0 +1,89 @@ +#![feature(linked_list_cursors)] +use std::{collections::HashSet, ptr::from_mut}; + +pub type Coords = (usize, usize, usize); + +#[unsafe(no_mangle)] +pub extern "Rust" fn challenge_usize(buf: &[u8]) -> usize { + let ln_iter = buf[..(buf.len() - 1)].split(|&b| b == b'\n'); + + let mut circuits: Vec> = Vec::new(); + + for ln in ln_iter { + let this_box = parse_jbox_ln(ln); + circuits.push(HashSet::new()); + circuits.last_mut().unwrap().insert(this_box); + } + + let mut prev_mul = None; + while let Some(this_mul) = merge_shortest_pair(&mut circuits) { + prev_mul = Some(this_mul); + } + + prev_mul.expect("not a single merge was done") +} + +fn distance(b1: Coords, b2: Coords) -> usize { + let a = b1.0 - b2.0; + let b = b1.1 - b2.1; + let c = b1.2 - b2.2; + + (a * a + b * b + c * c).isqrt() +} + +fn merge_shortest_pair(from: &mut Vec>) -> Option { + let mut min = None; + + for (i, circ) in unsafe { &mut *std::ptr::from_mut(from) } + .iter_mut() + .enumerate() + { + let raw_circ = from_mut(circ); + + for &coor in circ.iter() { + let rest_slice = &mut from[(i + 1)..]; + for other_circ in rest_slice.iter_mut() { + let raw_other_circ = from_mut(other_circ); + + for &coor2 in other_circ.iter() { + let dist = distance(coor, coor2); + + match min { + Some((min_dist, _, _, _, _)) => { + if min_dist > dist && dist != 0 { + min = + Some((dist, raw_circ, raw_other_circ, coor2, coor.0 * coor2.0)); + } + } + None => { + min = Some((dist, raw_circ, raw_other_circ, coor2, coor.0 * coor2.0)); + } + } + } + } + } + } + + if let Some((_, circ1, circ2, coor, that_mul)) = min { + let (circ1, circ2) = (unsafe { &mut *circ1 }, unsafe { &mut *circ2 }); + circ1.insert(coor); + circ2.remove(&coor); + Some(that_mul) + } else { + None + } +} + +fn parse_jbox_ln(ln: &[u8]) -> Coords { + let mut iter = ln.split(|&b| b == b',').map(|num_bytes| { + num_bytes + .iter() + .fold(0, |acc, b| acc * 10 + ((*b - b'0') as usize)) + }); + + ( + iter.next().unwrap(), + iter.next().unwrap(), + iter.next().unwrap(), + ) +}