use crate::error::RankAdapterError;
use std::collections::BTreeSet;
pub fn spanning_tree_swap_distance(a: &[usize], b: &[usize]) -> Result<usize, RankAdapterError> {
if a.len() != b.len() {
return Err(RankAdapterError::Invalid(
"spanning trees differ in edge count".to_string(),
));
}
let sb: BTreeSet<usize> = b.iter().copied().collect();
Ok(a.iter().filter(|id| !sb.contains(id)).count())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn identical_trees_have_zero_distance() {
assert_eq!(
spanning_tree_swap_distance(&[0, 1, 2], &[0, 1, 2]).unwrap(),
0
);
}
#[test]
fn one_edge_swap_is_distance_one() {
assert_eq!(
spanning_tree_swap_distance(&[0, 1, 2], &[0, 1, 3]).unwrap(),
1
);
}
#[test]
fn size_mismatch_rejected() {
assert!(matches!(
spanning_tree_swap_distance(&[0, 1], &[0, 1, 2]),
Err(RankAdapterError::Invalid(_))
));
}
}