Skip to content

Commit

Permalink
Merge pull request #109 from uesugi6111/add-permutation-iter
Browse files Browse the repository at this point in the history
add iter
  • Loading branch information
uesugi6111 authored Dec 2, 2023
2 parents cc10f0f + 883901a commit 8d72773
Showing 1 changed file with 57 additions and 0 deletions.
57 changes: 57 additions & 0 deletions src/math/permutation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,47 @@ fn push_recusive<T: Clone>(
vvec
}

pub struct Permutation<T>
where
T: Clone,
{
p: Vec<T>,
init: bool,
}

impl<T> Permutation<T>
where
T: Clone,
{
pub fn new(p: &[T]) -> Self {
Self {
p: p.to_vec(),
init: false,
}
}
}
impl<T> Iterator for Permutation<T>
where
T: Clone + Ord,
{
type Item = Vec<T>;

fn next(&mut self) -> Option<Self::Item> {
if !self.init {
self.p.sort();
self.init = true;
return Some(self.p.clone());
}
let Some(i) = (0..&self.p.len() - 1).rfind(|&i| self.p[i] < self.p[i + 1]) else {
return None;
};
let j = self.p.iter().rposition(|x| x > &self.p[i]).unwrap();
self.p.swap(i, j);
self.p[i + 1..].reverse();
Some(self.p.clone())
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand All @@ -45,4 +86,20 @@ mod tests {
let vv = make_permutation(4);
assert_eq!(0, vv[0][0]);
}
#[test]
fn test_struct() {
let expect = [
&[0, 1, 2],
&[0, 2, 1],
&[1, 0, 2],
&[1, 2, 0],
&[2, 0, 1],
&[2, 1, 0],
];
let a = Permutation::new(&[0, 1, 2]);

for (i, v) in a.enumerate() {
assert_eq!(v, expect[i]);
}
}
}

0 comments on commit 8d72773

Please sign in to comment.