use std::collections::{HashMap, HashSet};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct IvmCoordinate {
pub x: i32,
pub y: i32,
pub z: i32,
}
#[derive(Clone, Debug)]
pub struct IvmTopology {
pub nodes: HashMap<u64, IvmCoordinate>,
pub edges: HashMap<IvmCoordinate, HashSet<IvmCoordinate>>,
}
impl Default for IvmTopology {
fn default() -> Self {
Self::new()
}
}
impl IvmTopology {
pub fn new() -> Self {
let mut nodes = HashMap::new();
let mut edges = HashMap::new();
let mut qdu_counter = 0;
let grid_points = [-3, -1, 1, 3];
for &x in &grid_points {
for &y in &grid_points {
for &z in &grid_points {
let coord = IvmCoordinate { x, y, z };
nodes.insert(qdu_counter, coord);
qdu_counter += 1;
}
}
}
for (&_id_a, &coord_a) in &nodes {
let mut neighbors = HashSet::new();
for (&_id_b, &coord_b) in &nodes {
if coord_a == coord_b {
continue;
}
let dx = coord_a.x - coord_b.x;
let dy = coord_a.y - coord_b.y;
let dz = coord_a.z - coord_b.z;
let dist_sq = dx * dx + dy * dy + dz * dz;
if dist_sq == 4 {
neighbors.insert(coord_b);
}
}
edges.insert(coord_a, neighbors);
}
IvmTopology { nodes, edges }
}
pub fn are_adjacent(&self, qdu_a: u64, qdu_b: u64) -> bool {
if let (Some(coord_a), Some(coord_b)) = (self.nodes.get(&qdu_a), self.nodes.get(&qdu_b))
&& let Some(neighbors) = self.edges.get(coord_a)
{
return neighbors.contains(coord_b);
}
false
}
}