use std::ops::Mul;
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub struct Permutation {
pub mapping: Vec<usize>,
}
impl Permutation {
pub fn new(mapping: Vec<usize>) -> Self {
Self { mapping }
}
pub fn identity(size: usize) -> Self {
Self::new((0..size).collect())
}
pub fn size(&self) -> usize {
self.mapping.len()
}
pub fn apply(&self, i: usize) -> usize {
self.mapping[i]
}
pub fn inverse(&self) -> Self {
let mut inv = vec![0; self.size()];
for (i, &j) in self.mapping.iter().enumerate() {
inv[j] = i;
}
Self::new(inv)
}
}
impl Mul for Permutation {
type Output = Self;
fn mul(self, rhs: Self) -> Self::Output {
let mapping = (0..self.size()).map(|i| self.apply(rhs.apply(i))).collect();
Self::new(mapping)
}
}
#[cfg(test)]
mod tests {
use std::vec;
use super::Permutation;
#[test]
fn test_permutation() {
let permutation = Permutation::new(vec![1, 2, 0]);
assert_eq!(permutation.apply(0), 1);
assert_eq!(permutation.inverse(), Permutation::new(vec![2, 0, 1]));
assert_eq!(
permutation.clone() * permutation.inverse(),
Permutation::identity(3)
);
}
}