1
0

Add common::geometry::Point3 to simplify types in Playground solver

This commit is contained in:
Stefan Müller
2025-12-09 10:36:23 +01:00
parent 76b1e3cf89
commit 05cceddead
3 changed files with 27 additions and 12 deletions
+1
View File
@@ -1 +1,2 @@
pub mod geometry;
pub mod interval;
+10
View File
@@ -0,0 +1,10 @@
#[derive(Hash, PartialEq, Eq)]
pub struct Point3(pub u64, pub u64, pub u64);
impl Point3 {
pub fn distance_sqr(&self, other: &Self) -> u64 {
self.0.abs_diff(other.0).pow(2)
+ self.1.abs_diff(other.1).pow(2)
+ self.2.abs_diff(other.2).pow(2)
}
}
+16 -12
View File
@@ -1,3 +1,4 @@
use crate::common::geometry::Point3;
use crate::solvers::Solver;
use std::collections::{BTreeMap, HashSet};
use std::io::BufRead;
@@ -7,6 +8,8 @@ pub struct Playground {
}
impl Playground {
const CIRCUITS_TAKE: usize = 3;
pub fn new(connections: Option<usize>) -> Playground {
Playground {
connections: connections.unwrap_or(1000),
@@ -14,11 +17,11 @@ impl Playground {
}
// Collects all junction box coordinates.
fn junction_boxes<R: BufRead>(reader: R) -> Vec<(u64, u64, u64)> {
fn junction_boxes<R: BufRead>(reader: R) -> Vec<Point3> {
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.push(Point3(j[0], j[1], j[2]));
}
junction_boxes
}
@@ -27,13 +30,13 @@ impl Playground {
// connections.
fn distances<'a>(
&self,
junction_boxes: &'a Vec<(u64, u64, u64)>,
) -> BTreeMap<u64, (&'a (u64, u64, u64), &'a (u64, u64, u64))> {
junction_boxes: &'a Vec<Point3>,
) -> BTreeMap<u64, (&'a Point3, &'a Point3)> {
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);
let d = junction_boxes[i].distance_sqr(b);
distances.insert(d, (&junction_boxes[i], b));
if distances.len() > self.connections {
distances.pop_last();
@@ -43,8 +46,9 @@ impl Playground {
distances
}
fn circuit_sizes(distances: &BTreeMap<u64, (&(u64, u64, u64), &(u64, u64, u64))>) -> u64 {
let mut circuits: Vec<HashSet<&(u64, u64, u64)>> = Vec::new();
// Aggregates all circuits and returns the product of the sizes of the 3 largest ones.
fn circuit_sizes(distances: &BTreeMap<u64, (&Point3, &Point3)>) -> u64 {
let mut circuits: Vec<HashSet<&Point3>> = 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));
@@ -74,11 +78,11 @@ impl Playground {
}
}
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)
circuits
.iter()
.take(Self::CIRCUITS_TAKE)
.map(|c| c.len() as u64)
.product()
}
}