Skip to content

Commit 1c1f50a

Browse files
committed
2025 08.2
1 parent d01c800 commit 1c1f50a

File tree

1 file changed

+82
-7
lines changed

1 file changed

+82
-7
lines changed

src/aoc/y2025/day08.rs

Lines changed: 82 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use std::{cmp::Ordering, collections::HashSet};
1111

1212
use itertools::Itertools;
1313

14-
use crate::{AoCResult, Coord3D};
14+
use crate::Coord3D;
1515

1616
// now you're just being intentionally anonying ¬_¬
1717
fn dist(a: Coord3D, b: Coord3D) -> i64 {
@@ -20,18 +20,18 @@ fn dist(a: Coord3D, b: Coord3D) -> i64 {
2020
+ (a.z as i64 - b.z as i64).pow(2)
2121
}
2222

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
23+
fn get_distances(coords: Vec<Coord3D>) -> Vec<(i64, (Coord3D, Coord3D))> {
24+
coords
2625
.into_iter()
2726
.array_combinations()
2827
.map(|[a, b]| (dist(a, b), (a, b)))
2928
.sorted_unstable()
30-
.collect())
29+
.collect()
3130
}
3231

3332
pub fn part_1(data: crate::DataIn, num_connections: usize) -> crate::AoCResult<String> {
34-
let distances = get_distances(data)?;
33+
let coords: Vec<Coord3D> = data.map(|line| line.parse()).try_collect()?;
34+
let distances = get_distances(coords);
3535

3636
log::trace!("distances! {distances:?}");
3737

@@ -91,12 +91,87 @@ pub fn part_1(data: crate::DataIn, num_connections: usize) -> crate::AoCResult<S
9191
Ok(ret.to_string())
9292
}
9393

94+
pub fn part_2(data: crate::DataIn) -> crate::AoCResult<String> {
95+
let coords: Vec<Coord3D> = data.map(|line| line.parse()).try_collect()?;
96+
let mut circuits: Vec<HashSet<Coord3D>> = coords
97+
.iter()
98+
.map(|coord| [*coord].into_iter().collect())
99+
.collect();
100+
let distances = get_distances(coords);
101+
102+
log::trace!("distances! {distances:?}");
103+
104+
let mut ret = 0;
105+
106+
for (distance, (a, b)) in distances.iter() {
107+
log::debug!("Looking at pair {a}, {b} with distance {distance}!");
108+
109+
let a_circuit = circuits
110+
.iter()
111+
.find_position(|col| col.contains(a))
112+
.map(|(pos, _)| pos);
113+
let b_circuit = circuits
114+
.iter()
115+
.find_position(|col| col.contains(b))
116+
.map(|(pos, _)| pos);
117+
match (a_circuit, b_circuit) {
118+
(None, None) => {
119+
log::debug!("New circuit time");
120+
circuits.push([a, b].into_iter().copied().collect())
121+
}
122+
(Some(pos), None) => {
123+
log::debug!("a is already in a circuit, adding b");
124+
circuits[pos].insert(*b);
125+
}
126+
(None, Some(pos)) => {
127+
log::debug!("b is already in a circuit, adding a");
128+
circuits[pos].insert(*a);
129+
}
130+
(Some(pos_a), Some(pos_b)) => {
131+
let (winner, loser) = match pos_a.cmp(&pos_b) {
132+
Ordering::Less => (pos_a, pos_b),
133+
Ordering::Equal => {
134+
log::debug!("They're already in the same circuit!");
135+
// both in same circuit
136+
continue;
137+
}
138+
Ordering::Greater => (pos_b, pos_a),
139+
};
140+
log::debug!("Both in separate circuits, merging!");
141+
let loser = circuits.swap_remove(loser);
142+
circuits[winner].extend(loser);
143+
if circuits.len() == 1 {
144+
log::debug!("Fully merginated!");
145+
// we're fully merged
146+
ret = a.x as i64 * b.x as i64;
147+
break;
148+
}
149+
}
150+
}
151+
}
152+
153+
// log::debug!("There are {} circuits!", circuits.len());
154+
//
155+
// let ret: usize = circuits
156+
// .into_iter()
157+
// .map(|circuit| circuit.len())
158+
// .sorted_unstable()
159+
// .rev()
160+
// .take(3)
161+
// .inspect(|c| log::debug!("Final circuit size {c}"))
162+
// .product();
163+
Ok(ret.to_string())
164+
}
165+
94166
inventory::submit!(crate::AoCDay {
95167
year: "2025",
96168
day: "8",
97169
part_1: crate::AoCPart {
98170
main: |data| part_1(data, 1000),
99171
example: |data| part_1(data, 10)
100172
},
101-
part_2: None
173+
part_2: Some(crate::AoCPart {
174+
main: part_2,
175+
example: part_2
176+
})
102177
});

0 commit comments

Comments
 (0)