Skip to content

Commit 4e8a74e

Browse files
committed
chore: y2025::day_08
1 parent ad69dc7 commit 4e8a74e

File tree

5 files changed

+111
-2
lines changed

5 files changed

+111
-2
lines changed

.run/run_aoc.run.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<component name="ProjectRunConfigurationManager">
22
<configuration default="false" name="run_aoc" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
33
<option name="buildProfileId" value="dev" />
4-
<option name="command" value="run --package aoclp_solutions --bin aoclp_solutions -- --year 2025 --day 7" />
4+
<option name="command" value="run --package aoclp_solutions --bin aoclp_solutions -- --year 2025 --day 8" />
55
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
66
<envs />
77
<option name="emulateTerminal" value="true" />

aoclp/src/positioning/pt_3d.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use std::ops::{Add, AddAssign, RangeBounds, Sub, SubAssign};
44
use std::str::FromStr;
55
use std::sync::OnceLock;
66

7+
use num::{cast, NumCast};
8+
79
use crate::captures::CapturesHelper;
810
use crate::num::{zero, Signed, Zero};
911
use crate::regex::Regex;
@@ -26,6 +28,7 @@ impl<T> Pt3d<T>
2628
where
2729
T: PartialOrd,
2830
{
31+
/// Checks if this [`Pt3d`] is within the given bounds.
2932
pub fn within<XR, YR, ZR>(&self, x_bounds: XR, y_bounds: YR, z_bounds: ZR) -> bool
3033
where
3134
XR: RangeBounds<T>,
@@ -36,6 +39,29 @@ where
3639
}
3740
}
3841

42+
impl<T> Pt3d<T>
43+
where
44+
T: NumCast,
45+
{
46+
/// Casts this [`Pt3d`] to another numeric type.
47+
///
48+
/// # Examples
49+
///
50+
/// ```
51+
/// use aoclp::positioning::pt_3d::Pt3d;
52+
///
53+
/// let p: Pt3d<i32> = Pt3d::new(42, 23, 11);
54+
/// let fp: Pt3d<f64> = p.cast();
55+
/// assert_eq!(Pt3d::new(42.0, 23.0, 11.0), fp);
56+
/// ```
57+
pub fn cast<U>(self) -> Pt3d<U>
58+
where
59+
U: NumCast,
60+
{
61+
Pt3d::new(cast(self.x).unwrap(), cast(self.y).unwrap(), cast(self.z).unwrap())
62+
}
63+
}
64+
3965
impl<T, U, V, W> From<(U, V, W)> for Pt3d<T>
4066
where
4167
U: Into<T>,
@@ -157,3 +183,14 @@ where
157183
{
158184
(a.x - b.x).abs() + (a.y - b.y).abs() + (a.z - b.z).abs()
159185
}
186+
187+
/// Returns the [Euclidian distance] between two points in 3D space.
188+
///
189+
/// [Euclidian distance]: https://en.wikipedia.org/wiki/Euclidean_distance
190+
pub fn euclidian<T>(a: Pt3d<T>, b: Pt3d<T>) -> f64
191+
where
192+
T: NumCast,
193+
{
194+
let (a, b) = (a.cast::<f64>(), b.cast::<f64>());
195+
((a.x - b.x).abs().powi(2) + (a.y - b.y).abs().powi(2) + (a.z - b.z).abs().powi(2)).sqrt()
196+
}

aoclp_solutions/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ pub mod y2025;
1111
build_solvers! {
1212
{ 2017, [01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25] },
1313
{ 2024, [01, 02, 03, 04, 05, 06, 07, 08, 09, 10] },
14-
{ 2025, [01, 02, 03, 04, 05, 06, 07] }
14+
{ 2025, [01, 02, 03, 04, 05, 06, 07, 08] }
1515
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
use std::collections::HashMap;
2+
3+
use aoclp::num::Zero;
4+
use aoclp::positioning::pt_3d::{euclidian, Pt3d};
5+
use aoclp::solvers_impl::input::safe_get_input_as_many;
6+
use itertools::Itertools;
7+
8+
pub fn part_1() -> usize {
9+
circuits(false)
10+
.1
11+
.values()
12+
.sorted_unstable_by(|a, b| a.cmp(b).reverse())
13+
.take(3)
14+
.product()
15+
}
16+
17+
pub fn part_2() -> i64 {
18+
let (_, _, (a, b)) = circuits(true);
19+
a.x * b.x
20+
}
21+
22+
fn circuits(all: bool) -> (HashMap<Pt3d, usize>, HashMap<usize, usize>, (Pt3d, Pt3d)) {
23+
let boxes = input();
24+
25+
let mut circuit_id = 0usize;
26+
let mut circuits = HashMap::new();
27+
let mut circuit_sizes = HashMap::new();
28+
let mut last_pair = (Pt3d::zero(), Pt3d::zero());
29+
boxes
30+
.into_iter()
31+
.array_combinations()
32+
.filter(|&[a, b]| a != b)
33+
.map(|[a, b]| (a, b, euclidian(a, b)))
34+
.sorted_unstable_by(|(_, _, a), (_, _, b)| a.partial_cmp(b).unwrap())
35+
.take(if all { 1_000_000 } else { 1_000 })
36+
.for_each(|(a, b, _)| match (circuits.get(&a).copied(), circuits.get(&b).copied()) {
37+
(Some(a_id), Some(b_id)) if a_id == b_id => (),
38+
(Some(a_id), Some(b_id)) => {
39+
circuits.iter_mut().for_each(|(_, id)| {
40+
if *id == b_id {
41+
*id = a_id;
42+
}
43+
});
44+
45+
let b_size = circuit_sizes.remove(&b_id).unwrap();
46+
*circuit_sizes.get_mut(&a_id).unwrap() += b_size;
47+
48+
last_pair = (a, b);
49+
},
50+
(Some(a_id), None) => {
51+
circuits.insert(b, a_id);
52+
*circuit_sizes.get_mut(&a_id).unwrap() += 1;
53+
},
54+
(None, Some(b_id)) => {
55+
circuits.insert(a, b_id);
56+
*circuit_sizes.get_mut(&b_id).unwrap() += 1;
57+
},
58+
(None, None) => {
59+
circuits.insert(a, circuit_id);
60+
circuits.insert(b, circuit_id);
61+
circuit_sizes.insert(circuit_id, 2usize);
62+
circuit_id += 1;
63+
},
64+
});
65+
66+
(circuits, circuit_sizes, last_pair)
67+
}
68+
69+
fn input() -> Vec<Pt3d> {
70+
safe_get_input_as_many(2025, 8)
71+
}

aoclp_solutions/src/y2025/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ pub mod day_04;
55
pub mod day_05;
66
pub mod day_06;
77
pub mod day_07;
8+
pub mod day_08;

0 commit comments

Comments
 (0)