Add messy day 8
parent
35023c79a2
commit
33362cef62
|
|
@ -5,4 +5,6 @@ edition = "2024"
|
|||
|
||||
[dependencies]
|
||||
colored = "3.0.0"
|
||||
itertools = "0.14.0"
|
||||
petgraph = "0.8.3"
|
||||
regex = "1.12.2"
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,5 +1,129 @@
|
|||
// use crate::utils;
|
||||
use crate::utils;
|
||||
use itertools::Itertools;
|
||||
use petgraph::unionfind::UnionFind;
|
||||
use std::collections::{BinaryHeap, HashMap};
|
||||
|
||||
pub fn answer(_text: String) -> (u32, u32) {
|
||||
( 0, 0 )
|
||||
const COORD_SPACE: usize = 1000;
|
||||
const MAX_PAIRS: usize = 1000;
|
||||
|
||||
pub fn answer(text: String) -> (usize, u32) {
|
||||
// Get coordinates
|
||||
let coords: [Coord; COORD_SPACE] = text.trim()
|
||||
.split_whitespace()
|
||||
.filter_map(Coord::from)
|
||||
.collect::<Vec<Coord>>()
|
||||
.try_into()
|
||||
.unwrap();
|
||||
|
||||
// Find all equivalence classes
|
||||
let pairs = PairQueue::from(&coords);
|
||||
let mut uf = UnionFind::new(COORD_SPACE);
|
||||
|
||||
for ( c1, c2 ) in pairs.pairs.iter().rev().map(|cp| (cp.c1, cp.c2)) {
|
||||
// println!("Coord {c1} ({:?}) and coord {c2} ({:?}) are close together!", coords[c1], coords[c2]);
|
||||
uf.union(c1, c2);
|
||||
}
|
||||
println!("{:?}", uf);
|
||||
|
||||
// Collect sizes of equivalence classes
|
||||
let mut groups: HashMap<usize, usize> = HashMap::new();
|
||||
for x in uf.into_labeling().iter() {
|
||||
*groups.entry(*x).or_insert(0) += 1;
|
||||
}
|
||||
println!("{:?}", groups);
|
||||
|
||||
let mut equiv_class_sizes : Vec<isize> = groups
|
||||
.values()
|
||||
.map(|v| -1 * (*v as isize))
|
||||
.collect();
|
||||
equiv_class_sizes.sort_unstable();
|
||||
|
||||
println!("{:?}", equiv_class_sizes);
|
||||
|
||||
( (equiv_class_sizes[0] * equiv_class_sizes[1] * equiv_class_sizes[2]).abs() as usize
|
||||
// 87048 too high
|
||||
, 0
|
||||
)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Coord { x: u64, y: u64, z: u64, }
|
||||
impl Coord {
|
||||
fn dist_euclid(&self, other: &Coord) -> i64 {
|
||||
( self.x.abs_diff(other.x).pow(2)
|
||||
+ self.y.abs_diff(other.y).pow(2)
|
||||
+ self.z.abs_diff(other.z).pow(2)
|
||||
) as i64
|
||||
}
|
||||
|
||||
fn from(s: &str) -> Option<Coord> {
|
||||
let ( x, yz ) = s.split_once(",")?;
|
||||
let ( y, z ) = yz.split_once(",")?;
|
||||
|
||||
Some(Coord {
|
||||
x: utils::str_to_u64(x)?,
|
||||
y: utils::str_to_u64(y)?,
|
||||
z: utils::str_to_u64(z)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
struct CoordPair {
|
||||
distance: i64,
|
||||
c1 : usize,
|
||||
c2 : usize,
|
||||
}
|
||||
|
||||
struct PairQueue {
|
||||
max_distance: i64,
|
||||
pairs: BinaryHeap<CoordPair>,
|
||||
}
|
||||
impl PairQueue {
|
||||
fn from(coords: &[Coord; COORD_SPACE]) -> PairQueue {
|
||||
let pairs = coords
|
||||
.iter()
|
||||
.enumerate()
|
||||
.combinations(2);
|
||||
let mut queue = PairQueue::new();
|
||||
|
||||
for pair in pairs {
|
||||
let (i, c1) = pair[0];
|
||||
let (j, c2) = pair[1];
|
||||
|
||||
queue.insert(
|
||||
CoordPair { distance: c1.dist_euclid(c2), c1: i, c2: j }
|
||||
);
|
||||
}
|
||||
|
||||
queue
|
||||
}
|
||||
|
||||
fn insert(&mut self, pair: CoordPair) {
|
||||
// println!("At max: {} (size {}) | Distance = {} | Max distance = {} (too large: {})", self.pairs.len() >= MAX_PAIRS, self.pairs.len(), pair.distance, self.max_distance, pair.distance >= self.max_distance);
|
||||
if self.pairs.len() >= MAX_PAIRS && pair.distance >= self.max_distance {
|
||||
// println!("STOPPING!");
|
||||
return;
|
||||
}
|
||||
|
||||
self.max_distance = self.pairs
|
||||
.peek()
|
||||
.map(|cp| cp.distance)
|
||||
.unwrap_or(pair.distance)
|
||||
.max(pair.distance);
|
||||
// println!("Going on! Self distance = {}, pair distance = {}", self.max_distance, pair.distance);
|
||||
|
||||
self.pairs.push(pair);
|
||||
if self.pairs.len() > MAX_PAIRS {
|
||||
self.pairs.pop();
|
||||
// println!("Popping {:?}", self.pairs.pop());
|
||||
}
|
||||
}
|
||||
|
||||
fn new() -> PairQueue {
|
||||
PairQueue {
|
||||
max_distance: 0,
|
||||
pairs: BinaryHeap::with_capacity(COORD_SPACE + 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,10 @@ pub fn str_to_i16(s : &str) -> Option<i16> {
|
|||
s.trim().to_string().parse::<i16>().ok()
|
||||
}
|
||||
|
||||
pub fn str_to_i64(s : &str) -> Option<i64> {
|
||||
s.trim().to_string().parse::<i64>().ok()
|
||||
}
|
||||
|
||||
// pub fn str_to_i32(s : &str) -> Option<i32> {
|
||||
// s.trim().to_string().parse::<i32>().ok()
|
||||
// }
|
||||
|
|
|
|||
Loading…
Reference in New Issue