Skip to content

Commit 8e067eb

Browse files
committed
[2025] Solution for Day 8
1 parent 2f1175c commit 8e067eb

File tree

6 files changed

+221
-2
lines changed

6 files changed

+221
-2
lines changed

2025/src/bin/day07.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use aoc2025::days::day06::{part1, part2};
1+
use aoc2025::days::day07::{part1, part2};
22
use std::env;
33
use std::fs;
44
use std::process;

2025/src/bin/day08.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
use aoc2025::days::day08::{part1, part2};
2+
use std::env;
3+
use std::fs;
4+
use std::process;
5+
6+
fn main() {
7+
let args: Vec<String> = env::args().collect();
8+
if args.len() < 3 {
9+
println!("Missing required arguments");
10+
process::exit(1);
11+
}
12+
13+
let contents = fs::read_to_string(&args[1]).expect("Something went wrong");
14+
let count: usize = args[2].parse().expect("Invalid number for count");
15+
println!("Part 1: {}", part1(&contents, count));
16+
println!("Part 2: {}", part2(&contents));
17+
}

2025/src/days.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ pub mod day04;
55
pub mod day05;
66
pub mod day06;
77
pub mod day07;
8+
pub mod day08;

2025/src/days/day08.rs

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
use core::panic;
2+
use std::collections::{HashMap, HashSet};
3+
4+
#[derive(Eq, Hash, PartialEq)]
5+
struct Point {
6+
x: i64,
7+
y: i64,
8+
z: i64,
9+
}
10+
11+
impl Point {
12+
fn distance(&self, other: &Point) -> f64 {
13+
(((self.x - other.x).pow(2) + (self.y - other.y).pow(2) + (self.z - other.z).pow(2)) as f64)
14+
.sqrt()
15+
}
16+
}
17+
18+
pub fn part1(contents: &str, count: usize) -> i64 {
19+
let junction_boxes = parse_input(contents);
20+
let mut distances = Vec::new();
21+
for i in 0..junction_boxes.len() {
22+
for j in i + 1..junction_boxes.len() {
23+
let distance = junction_boxes[i].distance(&junction_boxes[j]);
24+
distances.push((distance, i, j));
25+
}
26+
}
27+
distances.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap());
28+
let mut graph = HashMap::new();
29+
for distance in distances.iter().take(count) {
30+
graph
31+
.entry(distance.1)
32+
.or_insert(Vec::new())
33+
.push(distance.2);
34+
graph
35+
.entry(distance.2)
36+
.or_insert(Vec::new())
37+
.push(distance.1);
38+
}
39+
40+
let mut circuits = Vec::new();
41+
let mut visited = vec![false; junction_boxes.len()];
42+
for i in 0..junction_boxes.len() {
43+
if !visited[i] {
44+
let mut count = 0;
45+
let mut stack = vec![i];
46+
while let Some(node) = stack.pop() {
47+
if !visited[node] {
48+
count += 1;
49+
visited[node] = true;
50+
if let Some(neighbors) = graph.get(&node) {
51+
for &neighbor in neighbors.iter() {
52+
if !visited[neighbor] {
53+
stack.push(neighbor);
54+
}
55+
}
56+
}
57+
}
58+
}
59+
circuits.push(count);
60+
}
61+
}
62+
circuits.sort_by(|a, b| b.cmp(a));
63+
circuits.iter().take(3).product()
64+
}
65+
66+
pub fn part2(contents: &str) -> i64 {
67+
let junction_boxes = parse_input(contents);
68+
let mut distances = Vec::new();
69+
for i in 0..junction_boxes.len() {
70+
for j in i + 1..junction_boxes.len() {
71+
let distance = junction_boxes[i].distance(&junction_boxes[j]);
72+
distances.push((distance, i, j));
73+
}
74+
}
75+
distances.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap());
76+
let mut graph = HashMap::new();
77+
for distance in distances {
78+
graph
79+
.entry(distance.1)
80+
.or_insert(Vec::new())
81+
.push(distance.2);
82+
graph
83+
.entry(distance.2)
84+
.or_insert(Vec::new())
85+
.push(distance.1);
86+
87+
let junction_count = count_junction_boxes(&graph, distance.1);
88+
if junction_count == junction_boxes.len() {
89+
return junction_boxes[distance.1].x * junction_boxes[distance.2].x;
90+
}
91+
}
92+
panic!("No solution found");
93+
}
94+
95+
fn parse_input(contents: &str) -> Vec<Point> {
96+
contents
97+
.lines()
98+
.map(|line| {
99+
let coords: Vec<i64> = line.split(',').map(|c| c.parse().unwrap()).collect();
100+
Point {
101+
x: coords[0],
102+
y: coords[1],
103+
z: coords[2],
104+
}
105+
})
106+
.collect()
107+
}
108+
109+
fn count_junction_boxes(graph: &HashMap<usize, Vec<usize>>, start: usize) -> usize {
110+
let mut visited = HashSet::new();
111+
let mut count = 0;
112+
let mut stack = vec![start];
113+
while let Some(node) = stack.pop() {
114+
if !visited.contains(&node) {
115+
count += 1;
116+
visited.insert(node);
117+
if let Some(neighbors) = graph.get(&node) {
118+
for &neighbor in neighbors.iter() {
119+
if !visited.contains(&neighbor) {
120+
stack.push(neighbor);
121+
}
122+
}
123+
}
124+
}
125+
}
126+
count
127+
}
128+
129+
#[cfg(test)]
130+
mod tests {
131+
use super::*;
132+
133+
#[test]
134+
fn test_part1() {
135+
let input = vec![
136+
"162,817,812",
137+
"57,618,57",
138+
"906,360,560",
139+
"592,479,940",
140+
"352,342,300",
141+
"466,668,158",
142+
"542,29,236",
143+
"431,825,988",
144+
"739,650,466",
145+
"52,470,668",
146+
"216,146,977",
147+
"819,987,18",
148+
"117,168,530",
149+
"805,96,715",
150+
"346,949,466",
151+
"970,615,88",
152+
"941,993,340",
153+
"862,61,35",
154+
"984,92,344",
155+
"425,690,689",
156+
];
157+
158+
assert_eq!(part1(&input.join("\n"), 10), 40);
159+
}
160+
161+
#[test]
162+
fn test_part2() {
163+
let input = vec![
164+
"162,817,812",
165+
"57,618,57",
166+
"906,360,560",
167+
"592,479,940",
168+
"352,342,300",
169+
"466,668,158",
170+
"542,29,236",
171+
"431,825,988",
172+
"739,650,466",
173+
"52,470,668",
174+
"216,146,977",
175+
"819,987,18",
176+
"117,168,530",
177+
"805,96,715",
178+
"346,949,466",
179+
"970,615,88",
180+
"941,993,340",
181+
"862,61,35",
182+
"984,92,344",
183+
"425,690,689",
184+
];
185+
186+
assert_eq!(part2(&input.join("\n")), 25272);
187+
}
188+
}

2025/tests/day08.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use aoc2025::days::day08::{part1, part2};
2+
3+
#[test]
4+
fn test_part1() {
5+
let content = std::include_str!("../../private/inputs/2025/day08.txt");
6+
assert_eq!(part1(&content, 1000), 123234);
7+
}
8+
9+
#[test]
10+
fn test_part2() {
11+
let content = std::include_str!("../../private/inputs/2025/day08.txt");
12+
assert_eq!(part2(&content), 9259958565);
13+
}

private

0 commit comments

Comments
 (0)