use std::fmt::{self, Display};
#[derive(Debug, Clone, Copy)]
pub struct PathNode {
pub i: usize,
pub j: isize, pub is_snake: bool,
pub is_bootstrap: bool,
pub prev: Option<usize>,
}
impl PathNode {
pub fn new(
i: usize,
j: isize,
is_snake: bool,
is_bootstrap: bool,
prev: Option<usize>,
) -> Self {
Self {
i,
j,
is_snake,
is_bootstrap,
prev,
}
}
pub fn fmt_path(arena: &[PathNode], start_idx: usize) -> String {
format!("{}", PathFormatter { arena, start_idx })
}
pub fn previous_snake(arena: &[PathNode], idx: usize) -> Option<usize> {
let node = arena[idx];
if node.is_bootstrap {
return None;
}
if !node.is_snake {
if let Some(p) = node.prev {
return PathNode::previous_snake(arena, p);
}
}
Some(idx)
}
}
pub struct PathFormatter<'a> {
arena: &'a [PathNode],
start_idx: usize,
}
impl Display for PathFormatter<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[")?;
let mut curr = Some(self.start_idx);
let mut first = true;
while let Some(idx) = curr {
let Some(node) = self.arena.get(idx) else {
break;
};
if !first {
write!(f, ", ")?;
}
write!(f, "({},{})", node.i, node.j)?;
first = false;
if node.is_bootstrap {
break;
}
curr = node.prev;
}
write!(f, "]")
}
}