Rust
Not an easy one, mostly because I messed up my merge circuits function (Pop/remove first circuit, load into second, but the pop/remove messed up the indexes, so I was merging the wrong thing).
After getting that it was all good. Pt2 was trivial once pt1 was solved.
spoiler
#[derive(Debug)]
struct Circuits {
circuits: Vec<Vec<usize>>,
}
impl Circuits {
fn find_circuit(&mut self, i: usize) -> Option<usize> {
for (j, c) in &mut self.circuits.iter().enumerate() {
if c.contains(&i) {
return Some(j);
}
}
None
}
fn new_circuit(&mut self, i: usize, j: usize) {
self.circuits.push(vec![i, j]);
}
fn join_circuits(&mut self, i: usize, j: usize) {
let mut other = self.circuits.get(j).unwrap().clone();
self.circuits.get_mut(i).unwrap().append(&mut other);
self.circuits.remove(j);
}
fn append_circuit(&mut self, c: usize, x: usize) {
self.circuits.get_mut(c).unwrap().push(x);
}
fn top_three(&mut self) -> Vec<usize> {
let mut sizes = self
.circuits
.iter()
.map(|c| c.len())
.collect::<Vec<usize>>();
sizes.sort();
sizes.reverse();
sizes[0..3].to_vec()
}
}
type Pole = (isize, isize, isize);
fn dist_poles(p1: &Pole, p2: &Pole) -> f32 {
sqrt(
((p1.0 - p2.0) * (p1.0 - p2.0)) as f32
+ ((p1.1 - p2.1) * (p1.1 - p2.1)) as f32
+ ((p1.2 - p2.2) * (p1.2 - p2.2)) as f32,
)
}
#[test]
fn test_y2025_day8_part1() {
let input = include_str!("../../input/2025/day_8.txt");
let poles = input
.lines()
.map(|l| {
let [x, y, z] = l
.splitn(3, ",")
.map(|c| c.parse::<isize>().unwrap())
.collect::<Vec<isize>>()[..]
else {
panic!();
};
(x, y, z)
})
.collect::<Vec<Pole>>();
let len = poles.len();
let mut circuits: Circuits = Circuits { circuits: vec![] };
let mut pairs = vec![];
for i in 0..len {
let first = poles.get(i).unwrap();
for j in i + 1..len {
if i == j {
continue;
}
let second = poles.get(j).unwrap();
let dist = dist_poles(first, second);
pairs.push((dist, i, j));
}
}
pairs.sort_by(|a, b| {
if a.0 < b.0 {
Ordering::Less
} else {
Ordering::Greater
}
});
for (dist, a, b) in pairs[0..1000].iter() {
let first_circuit = circuits.find_circuit(*a);
let second_circuit = circuits.find_circuit(*b);
match (first_circuit, second_circuit) {
(None, None) => {
circuits.new_circuit(*a, *b);
}
(Some(c), None) => {
circuits.append_circuit(c, *b);
}
(None, Some(c)) => {
circuits.append_circuit(c, *a);
}
(Some(c1), Some(c2)) => {
if c1 != c2 {
circuits.join_circuits(c1, c2);
}
}
}
}
assert_eq!(circuits.top_three().iter().product::<usize>(), 66640)
}