Skip to content

Commit 0702674

Browse files
committed
feat(08/2025): solve first part
1 parent 1a27208 commit 0702674

File tree

4 files changed

+176
-13
lines changed

4 files changed

+176
-13
lines changed

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
| [Day 5: Cafeteria](src/solutions/year2025/day05.rs) | ⭐⭐ | 0.275 | 0.469 |
1919
| [Day 6: Trash Compactor](src/solutions/year2025/day06.rs) | ⭐⭐ | 0.117 | 2.577 |
2020
| [Day 7: Laboratories](src/solutions/year2025/day07.rs) | ⭐⭐ | 6.711 | 5.789 |
21-
| [Day 8: Playground](src/solutions/year2025/day08.rs) | | - | - |
21+
| [Day 8: Playground](src/solutions/year2025/day08.rs) | | 46.993 | - |
2222

2323
# 2024
2424

src/solutions/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub fn solution(puzzle_day: PuzzleDay) -> Box<dyn Solution> {
2222
5 => Box::new(year2025::day05::Day05),
2323
6 => Box::new(year2025::day06::Day06),
2424
7 => Box::new(year2025::day07::Day07),
25-
8 => Box::new(year2025::day08::Day08),
25+
8 => Box::new(year2025::day08::Day08::default()),
2626
_ => panic!("Day not exist"),
2727
},
2828
Year::Year2024 => match i {

src/solutions/year2025/day08.rs

Lines changed: 114 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,135 @@
11
use crate::solutions::Solution;
2+
use crate::utils::point3d::Point3D;
3+
use itertools::Itertools;
24

3-
pub struct Day08;
5+
const INPUT_CONNECTIONS: u64 = 1_000;
6+
7+
type Pair = (Point3D, Point3D);
8+
9+
pub struct Day08 {
10+
connections: u64,
11+
}
412

513
impl Solution for Day08 {
6-
fn part_one(&self, _input: &str) -> String {
7-
String::from("0")
14+
fn part_one(&self, input: &str) -> String {
15+
let junction_boxes = self.parse(input);
16+
let closest = self.closest(junction_boxes);
17+
18+
let mut circuits: Vec<Vec<Point3D>> = Vec::new();
19+
20+
for pair in closest {
21+
let left_circuit = circuits
22+
.iter()
23+
.position(|circuit| circuit.contains(&pair.0));
24+
25+
let right_circuit = circuits
26+
.iter()
27+
.position(|circuit| circuit.contains(&pair.1));
28+
29+
match (left_circuit, right_circuit) {
30+
(Some(left), Some(right)) => {
31+
if left == right {
32+
continue;
33+
}
34+
35+
for in_circuit in circuits[right].clone() {
36+
circuits[left].push(in_circuit);
37+
}
38+
circuits.remove(right);
39+
}
40+
(None, Some(right)) => circuits[right].push(pair.0),
41+
(Some(left), None) => circuits[left].push(pair.1),
42+
(None, None) => {
43+
let new_circuit = vec![pair.0, pair.1];
44+
45+
circuits.push(new_circuit);
46+
}
47+
}
48+
}
49+
50+
circuits
51+
.iter()
52+
.map(|circuit| circuit.len())
53+
.sorted()
54+
.rev()
55+
.take(3)
56+
.product::<usize>()
57+
.to_string()
858
}
959

1060
fn part_two(&self, _input: &str) -> String {
1161
String::from("0")
1262
}
1363
}
1464

65+
impl Day08 {
66+
fn parse(&self, input: &str) -> Vec<Point3D> {
67+
input.lines().map(|line| line.parse().unwrap()).collect()
68+
}
69+
70+
fn closest(&self, boxes: Vec<Point3D>) -> Vec<Pair> {
71+
let mut calculated: Vec<(f64, Pair)> = Vec::new();
72+
for i in 0..boxes.len() {
73+
for j in i + 1..boxes.len() {
74+
calculated.push((boxes[i].distance(&boxes[j]), (boxes[i], boxes[j])));
75+
}
76+
}
77+
78+
calculated.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap());
79+
80+
calculated
81+
.iter()
82+
.take(self.connections as usize)
83+
.map(|x| x.1)
84+
.collect()
85+
}
86+
}
87+
88+
impl Default for Day08 {
89+
fn default() -> Self {
90+
Self {
91+
connections: INPUT_CONNECTIONS,
92+
}
93+
}
94+
}
95+
1596
#[cfg(test)]
1697
mod tests {
1798
use crate::solutions::year2025::day08::Day08;
1899
use crate::solutions::Solution;
100+
const TEST_CONNECTIONS: u64 = 10;
19101

20-
const EXAMPLE: &str = r#""#;
21-
22-
#[test]
23-
fn part_one_example_test() {
24-
assert_eq!("0", Day08.part_one(EXAMPLE));
102+
impl Day08 {
103+
fn new_for_tests() -> Self {
104+
Self {
105+
connections: TEST_CONNECTIONS,
106+
}
107+
}
25108
}
26109

110+
const EXAMPLE: &str = r#"162,817,812
111+
57,618,57
112+
906,360,560
113+
592,479,940
114+
352,342,300
115+
466,668,158
116+
542,29,236
117+
431,825,988
118+
739,650,466
119+
52,470,668
120+
216,146,977
121+
819,987,18
122+
117,168,530
123+
805,96,715
124+
346,949,466
125+
970,615,88
126+
941,993,340
127+
862,61,35
128+
984,92,344
129+
425,690,689"#;
130+
27131
#[test]
28-
fn part_two_example_test() {
29-
assert_eq!("0", Day08.part_two(EXAMPLE));
132+
fn part_one_example_test() {
133+
assert_eq!("40", Day08::new_for_tests().part_one(EXAMPLE));
30134
}
31135
}

src/utils/point3d.rs

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use itertools::Itertools;
22
use std::fmt::{Display, Formatter};
3-
use std::ops::{Add, Mul};
3+
use std::ops::{Add, Mul, Sub};
4+
use std::str::FromStr;
45

56
#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
67
pub struct Point3D {
@@ -29,6 +30,12 @@ impl Point3D {
2930
z: self.z + 1,
3031
}
3132
}
33+
34+
pub fn distance(&self, other: &Self) -> f64 {
35+
let diff = *self - *other;
36+
37+
((diff.x.abs().pow(2) + diff.y.abs().pow(2) + diff.z.abs().pow(2)) as f64).sqrt()
38+
}
3239
}
3340

3441
impl From<&str> for Point3D {
@@ -43,6 +50,14 @@ impl From<&str> for Point3D {
4350
}
4451
}
4552

53+
impl FromStr for Point3D {
54+
type Err = ();
55+
56+
fn from_str(s: &str) -> Result<Self, Self::Err> {
57+
Ok(Self::from(s))
58+
}
59+
}
60+
4661
impl Add<Point3D> for Point3D {
4762
type Output = Self;
4863

@@ -59,8 +74,52 @@ impl Mul<isize> for Point3D {
5974
}
6075
}
6176

77+
impl Sub<Point3D> for Point3D {
78+
type Output = Self;
79+
80+
fn sub(self, rhs: Point3D) -> Self::Output {
81+
Self::new(self.x - rhs.x, self.y - rhs.y, self.z - rhs.z)
82+
}
83+
}
84+
6285
impl Display for Point3D {
6386
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
6487
write!(f, "({},{},{})", self.x, self.y, self.z)
6588
}
6689
}
90+
91+
#[cfg(test)]
92+
mod tests {
93+
use super::*;
94+
95+
#[test]
96+
fn test_distance() {
97+
let p1 = Point3D::new(1, 2, 3);
98+
let p2 = Point3D::new(4, 5, 6);
99+
100+
assert_eq!(p1.distance(&p2), 5.196152422706632);
101+
}
102+
103+
#[test]
104+
fn test_distance_to_self() {
105+
let p1 = Point3D::new(1, 2, 3);
106+
107+
assert_eq!(p1.distance(&p1), 0.0);
108+
}
109+
110+
#[test]
111+
fn test_distance_along_single_axis() {
112+
let p1 = Point3D::new(1, 2, 3);
113+
let p2 = Point3D::new(1, 2, 8);
114+
115+
assert_eq!(5.0, p1.distance(&p2));
116+
}
117+
118+
#[test]
119+
fn test_distance_from_origin() {
120+
let p1 = Point3D::new(3, 4, 0);
121+
let origin = Point3D::new(0, 0, 0);
122+
123+
assert_eq!(5.0, p1.distance(&origin));
124+
}
125+
}

0 commit comments

Comments
 (0)