1
0

Add solution for "Day 8: Playground", part 1

This commit is contained in:
Stefan Müller
2025-12-09 10:20:49 +01:00
parent 60a49cc5ce
commit 76b1e3cf89
4 changed files with 106 additions and 1 deletions
+4
View File
@@ -22,6 +22,10 @@ This project does not contain the puzzle or example inputs as per the [copyright
:mag_right: Puzzle: <https://adventofcode.com/2025/day/6>, :white_check_mark: Solver: [`TrashCompactor`](src/solvers/trash_compactor.rs)
### Day 8: Playground
:mag_right: Puzzle: <https://adventofcode.com/2025/day/8>, :white_check_mark: Solver: [`Playground`](src/solvers/playground.rs)
## Tests
The package contains unit tests for each solver to help troubleshoot issues and prevent regressions. These tests cover the solutions for provided examples and full data inputs. The solutions used within the tests are user-specific.
+5
View File
@@ -2,7 +2,12 @@ use advent_of_code_2025::solvers;
fn main() {
println!("### Advent of Code 2025 ###\n");
// SecretEntrance
// GiftShop
// Lobby
solvers::run(solvers::printing_department::PrintingDepartment {});
solvers::run(solvers::cafeteria::Cafeteria {});
solvers::run(solvers::trash_compactor::TrashCompactor {});
// Laboratories
solvers::run(solvers::playground::Playground::new(None));
}
+1
View File
@@ -6,6 +6,7 @@ use std::path;
use std::path::Path;
pub mod cafeteria;
pub mod playground;
pub mod printing_department;
pub mod trash_compactor;
+95
View File
@@ -0,0 +1,95 @@
use crate::solvers::Solver;
use std::collections::{BTreeMap, HashSet};
use std::io::BufRead;
pub struct Playground {
connections: usize,
}
impl Playground {
pub fn new(connections: Option<usize>) -> Playground {
Playground {
connections: connections.unwrap_or(1000),
}
}
// Collects all junction box coordinates.
fn junction_boxes<R: BufRead>(reader: R) -> Vec<(u64, u64, u64)> {
let mut junction_boxes = Vec::new();
for line in reader.lines().map_while(Result::ok) {
let j: Vec<u64> = line.split(',').map(|s| s.parse().unwrap()).collect();
junction_boxes.push((j[0], j[1], j[2]));
}
junction_boxes
}
// Maps the closest pairs of junction boxes to their distances, up to the maximum number of
// connections.
fn distances<'a>(
&self,
junction_boxes: &'a Vec<(u64, u64, u64)>,
) -> BTreeMap<u64, (&'a (u64, u64, u64), &'a (u64, u64, u64))> {
let mut distances = BTreeMap::new();
for i in 0..junction_boxes.len() {
let (_, right) = junction_boxes.split_at(i + 1);
for b in right {
let d = Self::distance_sqr(&junction_boxes[i], b);
distances.insert(d, (&junction_boxes[i], b));
if distances.len() > self.connections {
distances.pop_last();
}
}
}
distances
}
fn circuit_sizes(distances: &BTreeMap<u64, (&(u64, u64, u64), &(u64, u64, u64))>) -> u64 {
let mut circuits: Vec<HashSet<&(u64, u64, u64)>> = Vec::new();
for junction_boxes in distances.values() {
let index_a = circuits.iter().position(|c| c.contains(&junction_boxes.0));
let index_b = circuits.iter().position(|c| c.contains(&junction_boxes.1));
if let Some(index_a) = index_a {
if let Some(index_b) = index_b {
if index_a != index_b {
let (low, high) = if index_a < index_b {
(index_a, index_b)
} else {
(index_b, index_a)
};
let mut c = circuits.remove(high);
circuits[low].extend(c.drain());
}
} else {
circuits[index_a].insert(junction_boxes.1);
}
} else {
if let Some(index_b) = index_b {
circuits[index_b].insert(junction_boxes.0);
} else {
let mut set = HashSet::new();
set.insert(junction_boxes.0);
set.insert(junction_boxes.1);
circuits.push(set);
}
}
}
circuits.sort_by(|a, b| b.len().cmp(&a.len()));
circuits.iter().take(3).map(|c| c.len() as u64).product()
}
fn distance_sqr(a: &(u64, u64, u64), b: &(u64, u64, u64)) -> u64 {
a.0.abs_diff(b.0).pow(2) + a.1.abs_diff(b.1).pow(2) + a.2.abs_diff(b.2).pow(2)
}
}
impl Solver for Playground {
const PUZZLE_INDEX: u8 = 8;
const PUZZLE_NAME: &'static str = "Playground";
fn process_data<R: BufRead>(&self, reader: R) -> (u64, u64) {
let junction_boxes = Self::junction_boxes(reader);
let distances = self.distances(&junction_boxes);
(Self::circuit_sizes(&distances), 0)
}
}