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
+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)
}
}