Skip to content

Commit d01c800

Browse files
committed
2025 08.1
1 parent 27b04b3 commit d01c800

File tree

4 files changed

+118
-1
lines changed

4 files changed

+118
-1
lines changed

data

Submodule data updated from 73c0666 to f88c66e

src/aoc/y2025/day08.rs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// Copyright (c) 2025 Lexi Robinson
2+
//
3+
// Licensed under the EUPL, Version 1.2
4+
//
5+
// You may not use this work except in compliance with the Licence.
6+
// You should have received a copy of the Licence along with this work. If not, see:
7+
// <https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12>.
8+
// See the Licence for the specific language governing permissions and limitations under the Licence.
9+
10+
use std::{cmp::Ordering, collections::HashSet};
11+
12+
use itertools::Itertools;
13+
14+
use crate::{AoCResult, Coord3D};
15+
16+
// now you're just being intentionally anonying ¬_¬
17+
fn dist(a: Coord3D, b: Coord3D) -> i64 {
18+
(a.x as i64 - b.x as i64).pow(2)
19+
+ (a.y as i64 - b.y as i64).pow(2)
20+
+ (a.z as i64 - b.z as i64).pow(2)
21+
}
22+
23+
fn get_distances(data: crate::DataIn) -> AoCResult<Vec<(i64, (Coord3D, Coord3D))>> {
24+
let coords: Vec<Coord3D> = data.map(|line| line.parse()).try_collect()?;
25+
Ok(coords
26+
.into_iter()
27+
.array_combinations()
28+
.map(|[a, b]| (dist(a, b), (a, b)))
29+
.sorted_unstable()
30+
.collect())
31+
}
32+
33+
pub fn part_1(data: crate::DataIn, num_connections: usize) -> crate::AoCResult<String> {
34+
let distances = get_distances(data)?;
35+
36+
log::trace!("distances! {distances:?}");
37+
38+
let mut circuits: Vec<HashSet<Coord3D>> = Vec::with_capacity(num_connections);
39+
40+
for (distance, (a, b)) in distances[0..num_connections].iter() {
41+
log::debug!("Looking at pair {a}, {b} with distance {distance}!");
42+
43+
let a_circuit = circuits
44+
.iter()
45+
.find_position(|col| col.contains(a))
46+
.map(|(pos, _)| pos);
47+
let b_circuit = circuits
48+
.iter()
49+
.find_position(|col| col.contains(b))
50+
.map(|(pos, _)| pos);
51+
match (a_circuit, b_circuit) {
52+
(None, None) => {
53+
log::debug!("New circuit time");
54+
circuits.push([a, b].into_iter().copied().collect())
55+
}
56+
(Some(pos), None) => {
57+
log::debug!("a is already in a circuit, adding b");
58+
circuits[pos].insert(*b);
59+
}
60+
(None, Some(pos)) => {
61+
log::debug!("b is already in a circuit, adding a");
62+
circuits[pos].insert(*a);
63+
}
64+
(Some(pos_a), Some(pos_b)) => {
65+
let (winner, loser) = match pos_a.cmp(&pos_b) {
66+
Ordering::Less => (pos_a, pos_b),
67+
Ordering::Equal => {
68+
log::debug!("They're already in the same circuit!");
69+
// both in same circuit
70+
continue;
71+
}
72+
Ordering::Greater => (pos_b, pos_a),
73+
};
74+
log::debug!("Both in separate circuits, merging!");
75+
let loser = circuits.swap_remove(loser);
76+
circuits[winner].extend(loser);
77+
}
78+
}
79+
}
80+
81+
log::debug!("There are {} circuits!", circuits.len());
82+
83+
let ret: usize = circuits
84+
.into_iter()
85+
.map(|circuit| circuit.len())
86+
.sorted_unstable()
87+
.rev()
88+
.take(3)
89+
.inspect(|c| log::debug!("Final circuit size {c}"))
90+
.product();
91+
Ok(ret.to_string())
92+
}
93+
94+
inventory::submit!(crate::AoCDay {
95+
year: "2025",
96+
day: "8",
97+
part_1: crate::AoCPart {
98+
main: |data| part_1(data, 1000),
99+
example: |data| part_1(data, 10)
100+
},
101+
part_2: None
102+
});

src/aoc/y2025/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ pub mod day04;
1313
pub mod day05;
1414
pub mod day06;
1515
pub mod day07;
16+
pub mod day08;

src/utils/coord3d.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
// <https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12>.
88
// See the Licence for the specific language governing permissions and limitations under the Licence.
99

10+
use std::cmp;
1011
use std::fmt::Display;
1112
use std::ops;
1213
use std::str::FromStr;
@@ -231,3 +232,16 @@ impl TryFrom<(usize, usize, usize)> for Coord3D {
231232
})
232233
}
233234
}
235+
236+
impl Ord for Coord3D {
237+
fn cmp(&self, other: &Self) -> cmp::Ordering {
238+
// Incredibly basic comparison - more numbers = more ord
239+
(self.x + self.y + self.z).cmp(&(other.x + other.y + other.z))
240+
}
241+
}
242+
243+
impl PartialOrd for Coord3D {
244+
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
245+
Some(self.cmp(other))
246+
}
247+
}

0 commit comments

Comments
 (0)