use std::fmt;
use std::fmt::Debug;
#[derive(Clone, Debug)]
pub struct Path<T> {
v: Vec<T>,
len: usize,
exists: bool,
}
impl<T> Path<T> {
pub(crate) fn set_vector(&mut self, t: Vec<T>) {
self.v = t
}
pub fn get_slice<'a>(&'a self) -> &'a [T] {
&self.v
}
pub fn iter<'a>(&'a self) -> impl DoubleEndedIterator<Item = &'a T> {
self.v.iter()
}
pub fn len(&self) -> usize {
assert!(self.exists);
self.len
}
pub(crate) fn set_len(&mut self, v: usize) {
self.len = v;
self.exists = true;
}
pub fn exists(&self) -> bool {
self.exists
}
}
impl<T> AsRef<Vec<T>> for Path<T> {
fn as_ref(&self) -> &Vec<T> {
&self.v
}
}
impl<T> Default for Path<T> {
fn default() -> Self {
use std::usize::MAX;
Path {
v: Vec::new(),
len: MAX,
exists: false,
}
}
}
#[derive(Debug)]
pub struct PathMatrix<T> {
m: Box<[Path<T>]>,
n: usize,
}
impl<T> PathMatrix<T> {
pub fn new(n: usize) -> PathMatrix<T> {
let mut m = vec![];
let n_elems = 1 + n * (n - 1) / 2;
for _ in 0..n_elems {
m.push(Path::default());
}
let m = m.into();
PathMatrix { m, n }
}
fn idx(&self, mut i: usize, mut j: usize) -> usize {
if i > j {
::std::mem::swap(&mut i, &mut j);
}
assert!(i <= j);
if i == j {
0
} else {
if j < 3 {
j + i
} else {
let k = j - 1;
self.idx(0, j - 1) + k + i
}
}
}
pub fn get_path_len(&self, i: usize, j: usize) -> usize {
let idx = self.idx(i, j);
self.m[idx].len()
}
pub fn get_path(&self, i: usize, j: usize) -> &Path<T> {
let idx = self.idx(i, j);
&self.m[idx]
}
pub fn get_path_iter<'a>(
&'a self,
i: usize,
j: usize,
) -> impl DoubleEndedIterator<Item = &'a T> {
let idx = self.idx(i, j);
self.m[idx].iter()
}
pub fn does_path_exist(&self, i: usize, j: usize) -> bool {
let idx = self.idx(i, j);
self.m[idx].exists()
}
pub(crate) fn get_path_mut(&mut self, i: usize, j: usize) -> &mut Path<T> {
let idx = self.idx(i, j);
&mut self.m[idx]
}
pub fn set_path_len(&mut self, i: usize, j: usize, v: usize) {
let idx = self.idx(i, j);
self.m[idx].set_len(v);
}
}