pub trait RingSeq<T> {
Show 35 methods
// Required methods
fn index_from(&self, i: isize) -> usize;
fn apply_o(&self, i: isize) -> &T;
fn rotate_right(&self, step: isize) -> Vec<T>
where T: Clone;
fn rotate_left(&self, step: isize) -> Vec<T>
where T: Clone;
fn start_at(&self, i: isize) -> Vec<T>
where T: Clone;
fn reflect_at(&self, i: isize) -> Vec<T>
where T: Clone;
fn segment_length(&self, pred: impl Fn(&T) -> bool, from: isize) -> usize;
fn take_while(&self, pred: impl Fn(&T) -> bool, from: isize) -> Vec<T>
where T: Clone;
fn drop_while(&self, pred: impl Fn(&T) -> bool, from: isize) -> Vec<T>
where T: Clone;
fn span(&self, pred: impl Fn(&T) -> bool, from: isize) -> (Vec<T>, Vec<T>)
where T: Clone;
fn slice_o(&self, from: isize, to: isize) -> Vec<T>
where T: Clone;
fn contains_slice(&self, slice: &[T]) -> bool
where T: PartialEq;
fn index_of_slice(&self, slice: &[T], from: isize) -> Option<usize>
where T: PartialEq;
fn last_index_of_slice(&self, slice: &[T], end: isize) -> Option<usize>
where T: PartialEq;
fn circular_windows(&self, size: usize, step: usize) -> SlidingO<T> ⓘ
where T: Clone;
fn circular_chunks(&self, size: usize) -> SlidingO<T> ⓘ
where T: Clone;
fn circular_enumerate(&self, from: isize) -> Vec<(T, usize)>
where T: Clone;
fn rotations(&self) -> Rotations<'_, T> ⓘ;
fn reflections(&self) -> Reflections<'_, T> ⓘ;
fn reversions(&self) -> Reversions<'_, T> ⓘ;
fn rotations_and_reflections(&self) -> RotationsAndReflections<'_, T> ⓘ
where T: Clone;
fn is_rotation_of(&self, that: &[T]) -> bool
where T: PartialEq;
fn is_reflection_of(&self, that: &[T]) -> bool
where T: PartialEq + Clone;
fn is_reversion_of(&self, that: &[T]) -> bool
where T: PartialEq;
fn is_rotation_or_reflection_of(&self, that: &[T]) -> bool
where T: PartialEq + Clone;
fn rotation_offset(&self, that: &[T]) -> Option<usize>
where T: PartialEq;
fn hamming_distance(&self, that: &[T]) -> usize
where T: PartialEq;
fn min_rotational_hamming_distance(&self, that: &[T]) -> usize
where T: PartialEq + Clone;
fn canonical_index(&self) -> usize
where T: Ord;
fn canonical(&self) -> Vec<T>
where T: Clone + Ord;
fn bracelet(&self) -> Vec<T>
where T: Clone + Ord;
fn rotational_symmetry(&self) -> usize
where T: PartialEq;
fn symmetry_indices(&self) -> Vec<usize>
where T: PartialEq;
fn reflectional_symmetry_axes(&self) -> Vec<(AxisLocation, AxisLocation)>
where T: PartialEq;
fn symmetry(&self) -> usize
where T: PartialEq;
}Expand description
Circular (ring) sequence operations on [T].
Import this trait to gain circular methods on slices, Vecs, and arrays:
use ring_seq::RingSeq;Required Methods§
Sourcefn index_from(&self, i: isize) -> usize
fn index_from(&self, i: isize) -> usize
Sourcefn rotate_right(&self, step: isize) -> Vec<T>where
T: Clone,
fn rotate_right(&self, step: isize) -> Vec<T>where
T: Clone,
Rotates the sequence to the right by step positions, returning a new
Vec.
A negative step rotates to the left.
§Examples
use ring_seq::RingSeq;
assert_eq!([0, 1, 2].rotate_right(1), vec![2, 0, 1]);
assert_eq!([0, 1, 2].rotate_right(-1), vec![1, 2, 0]);Sourcefn rotate_left(&self, step: isize) -> Vec<T>where
T: Clone,
fn rotate_left(&self, step: isize) -> Vec<T>where
T: Clone,
Rotates the sequence to the left by step positions, returning a new
Vec.
A negative step rotates to the right.
§Examples
use ring_seq::RingSeq;
assert_eq!([0, 1, 2].rotate_left(1), vec![1, 2, 0]);Sourcefn start_at(&self, i: isize) -> Vec<T>where
T: Clone,
fn start_at(&self, i: isize) -> Vec<T>where
T: Clone,
Rotates the sequence so that circular index i becomes the first
element.
Equivalent to rotate_left.
§Examples
use ring_seq::RingSeq;
assert_eq!([0, 1, 2].start_at(1), vec![1, 2, 0]);Sourcefn reflect_at(&self, i: isize) -> Vec<T>where
T: Clone,
fn reflect_at(&self, i: isize) -> Vec<T>where
T: Clone,
Reflects (reverses) the sequence and rotates so that circular index i
is the first element.
Equivalent to start_at(i + 1) followed by reverse.
§Examples
use ring_seq::RingSeq;
assert_eq!([0, 1, 2].reflect_at(0), vec![0, 2, 1]);Sourcefn segment_length(&self, pred: impl Fn(&T) -> bool, from: isize) -> usize
fn segment_length(&self, pred: impl Fn(&T) -> bool, from: isize) -> usize
Length of the longest prefix of elements, starting from circular index
from, that satisfy pred.
§Examples
use ring_seq::RingSeq;
assert_eq!([0, 1, 2].segment_length(|x| x % 2 == 0, 2), 2);Sourcefn take_while(&self, pred: impl Fn(&T) -> bool, from: isize) -> Vec<T>where
T: Clone,
fn take_while(&self, pred: impl Fn(&T) -> bool, from: isize) -> Vec<T>where
T: Clone,
Takes the longest prefix of elements, starting from circular index
from, that satisfy pred.
§Examples
use ring_seq::RingSeq;
assert_eq!([0, 1, 2, 3, 4].take_while(|&x| x < 3, 1), vec![1, 2]);Sourcefn drop_while(&self, pred: impl Fn(&T) -> bool, from: isize) -> Vec<T>where
T: Clone,
fn drop_while(&self, pred: impl Fn(&T) -> bool, from: isize) -> Vec<T>where
T: Clone,
Drops the longest prefix of elements, starting from circular index
from, that satisfy pred.
§Examples
use ring_seq::RingSeq;
assert_eq!([0, 1, 2, 3, 4].drop_while(|&x| x < 3, 1), vec![3, 4, 0]);Sourcefn span(&self, pred: impl Fn(&T) -> bool, from: isize) -> (Vec<T>, Vec<T>)where
T: Clone,
fn span(&self, pred: impl Fn(&T) -> bool, from: isize) -> (Vec<T>, Vec<T>)where
T: Clone,
Splits the circular sequence at the first element (starting from
circular index from) that does not satisfy pred.
Returns (take_while(pred, from), drop_while(pred, from)).
§Examples
use ring_seq::RingSeq;
let (a, b) = [0, 1, 2, 3, 4].span(|&x| x < 3, 1);
assert_eq!(a, vec![1, 2]);
assert_eq!(b, vec![3, 4, 0]);Sourcefn slice_o(&self, from: isize, to: isize) -> Vec<T>where
T: Clone,
fn slice_o(&self, from: isize, to: isize) -> Vec<T>where
T: Clone,
Selects a circular interval of elements from index from (inclusive)
to index to (exclusive).
The resulting slice can be longer than the ring when to - from
exceeds the ring length, because the ring repeats circularly.
Returns an empty Vec when from >= to or the ring is empty.
§Examples
use ring_seq::RingSeq;
assert_eq!([0, 1, 2].slice_o(-1, 4), vec![2, 0, 1, 2, 0]);
assert_eq!([0, 1, 2].slice_o(1, 3), vec![1, 2]);Sourcefn contains_slice(&self, slice: &[T]) -> boolwhere
T: PartialEq,
fn contains_slice(&self, slice: &[T]) -> boolwhere
T: PartialEq,
Tests whether this ring contains slice as a contiguous circular
subsequence.
The slice may wrap around the ring boundary and may even be longer than the ring (repeating elements are matched cyclically).
§Examples
use ring_seq::RingSeq;
assert!([0, 1, 2].contains_slice(&[2, 0, 1, 2, 0]));
assert!(![0, 1, 2].contains_slice(&[1, 0]));Sourcefn index_of_slice(&self, slice: &[T], from: isize) -> Option<usize>where
T: PartialEq,
fn index_of_slice(&self, slice: &[T], from: isize) -> Option<usize>where
T: PartialEq,
Finds the first circular index at or after from where slice appears
as a contiguous subsequence.
Returns None if not found.
§Examples
use ring_seq::RingSeq;
assert_eq!([0, 1, 2].index_of_slice(&[2, 0, 1, 2, 0], 0), Some(2));Sourcefn last_index_of_slice(&self, slice: &[T], end: isize) -> Option<usize>where
T: PartialEq,
fn last_index_of_slice(&self, slice: &[T], end: isize) -> Option<usize>where
T: PartialEq,
Finds the last circular index at or before end where slice appears
as a contiguous subsequence.
Returns None if not found.
§Examples
use ring_seq::RingSeq;
assert_eq!(
[0, 1, 2, 0, 1, 2].last_index_of_slice(&[2, 0], -1),
Some(5),
);Sourcefn circular_chunks(&self, size: usize) -> SlidingO<T> ⓘwhere
T: Clone,
fn circular_chunks(&self, size: usize) -> SlidingO<T> ⓘwhere
T: Clone,
Fixed-size circular groups (like circular_windows with
step == size).
§Panics
Panics if size is zero.
§Examples
use ring_seq::RingSeq;
let groups: Vec<_> = [0, 1, 2, 3, 4].circular_chunks(2).collect();
assert_eq!(
groups,
vec![vec![0, 1], vec![2, 3], vec![4, 0], vec![1, 2], vec![3, 4]],
);Sourcefn circular_enumerate(&self, from: isize) -> Vec<(T, usize)>where
T: Clone,
fn circular_enumerate(&self, from: isize) -> Vec<(T, usize)>where
T: Clone,
Pairs each element with its original (circular) index, starting from
circular index from.
§Examples
use ring_seq::RingSeq;
assert_eq!(
['a', 'b', 'c'].circular_enumerate(1),
vec![('b', 1), ('c', 2), ('a', 0)],
);Sourcefn rotations(&self) -> Rotations<'_, T> ⓘ
fn rotations(&self) -> Rotations<'_, T> ⓘ
All rotations of this ring.
Yields n items for a non-empty ring (starting from the identity
rotation), or a single empty Vec for an empty ring.
§Examples
use ring_seq::RingSeq;
let rots: Vec<_> = [0, 1, 2].rotations().collect();
assert_eq!(rots, vec![vec![0, 1, 2], vec![1, 2, 0], vec![2, 0, 1]]);Sourcefn reflections(&self) -> Reflections<'_, T> ⓘ
fn reflections(&self) -> Reflections<'_, T> ⓘ
The original ring and its reflection at index 0.
Yields 2 items for a non-empty ring, or a single empty Vec for an
empty ring.
§Examples
use ring_seq::RingSeq;
let refs: Vec<_> = [0, 1, 2].reflections().collect();
assert_eq!(refs, vec![vec![0, 1, 2], vec![0, 2, 1]]);Sourcefn reversions(&self) -> Reversions<'_, T> ⓘ
fn reversions(&self) -> Reversions<'_, T> ⓘ
The original ring and its reversal.
Yields 2 items for a non-empty ring, or a single empty Vec for an
empty ring.
§Examples
use ring_seq::RingSeq;
let revs: Vec<_> = [0, 1, 2].reversions().collect();
assert_eq!(revs, vec![vec![0, 1, 2], vec![2, 1, 0]]);Sourcefn rotations_and_reflections(&self) -> RotationsAndReflections<'_, T> ⓘwhere
T: Clone,
fn rotations_and_reflections(&self) -> RotationsAndReflections<'_, T> ⓘwhere
T: Clone,
All rotations of the original ring followed by all rotations of its reflection.
Yields 2n items for a non-empty ring, or a single empty Vec for an
empty ring.
§Examples
use ring_seq::RingSeq;
let all: Vec<_> = [0, 1, 2].rotations_and_reflections().collect();
assert_eq!(all, vec![
vec![0, 1, 2], vec![1, 2, 0], vec![2, 0, 1],
vec![0, 2, 1], vec![2, 1, 0], vec![1, 0, 2],
]);Sourcefn is_rotation_of(&self, that: &[T]) -> boolwhere
T: PartialEq,
fn is_rotation_of(&self, that: &[T]) -> boolwhere
T: PartialEq,
Tests whether this ring is a rotation of that.
Two sequences are rotations of each other iff they have the same length and one appears as a contiguous substring inside the other repeated twice.
§Examples
use ring_seq::RingSeq;
assert!([0, 1, 2].is_rotation_of(&[1, 2, 0]));
assert!(![0, 1, 2].is_rotation_of(&[0, 2, 1]));Sourcefn is_reflection_of(&self, that: &[T]) -> bool
fn is_reflection_of(&self, that: &[T]) -> bool
Tests whether this ring is the reflection at index 0 of that (or
identical to it).
This checks a single specific reflection axis. For rotation-insensitive
comparison, see is_rotation_or_reflection_of.
§Examples
use ring_seq::RingSeq;
assert!([0, 1, 2].is_reflection_of(&[0, 2, 1]));Sourcefn is_reversion_of(&self, that: &[T]) -> boolwhere
T: PartialEq,
fn is_reversion_of(&self, that: &[T]) -> boolwhere
T: PartialEq,
Tests whether this ring is the reversal of that (or identical to it).
§Examples
use ring_seq::RingSeq;
assert!([0, 1, 2].is_reversion_of(&[2, 1, 0]));Sourcefn is_rotation_or_reflection_of(&self, that: &[T]) -> bool
fn is_rotation_or_reflection_of(&self, that: &[T]) -> bool
Tests whether this ring is a rotation or a reflection of that.
§Examples
use ring_seq::RingSeq;
assert!([0, 1, 2].is_rotation_or_reflection_of(&[2, 0, 1]));
assert!([0, 1, 2].is_rotation_or_reflection_of(&[0, 2, 1]));Sourcefn rotation_offset(&self, that: &[T]) -> Option<usize>where
T: PartialEq,
fn rotation_offset(&self, that: &[T]) -> Option<usize>where
T: PartialEq,
Finds the rotation offset that aligns this ring with that.
Returns Some(k) such that self.start_at(k) == that, or None if no
rotation matches (or sizes differ).
§Examples
use ring_seq::RingSeq;
assert_eq!([0, 1, 2].rotation_offset(&[2, 0, 1]), Some(2));
assert_eq!([0, 1, 2].rotation_offset(&[0, 2, 1]), None);Sourcefn hamming_distance(&self, that: &[T]) -> usizewhere
T: PartialEq,
fn hamming_distance(&self, that: &[T]) -> usizewhere
T: PartialEq,
Sourcefn min_rotational_hamming_distance(&self, that: &[T]) -> usize
fn min_rotational_hamming_distance(&self, that: &[T]) -> usize
Sourcefn canonical_index(&self) -> usizewhere
T: Ord,
fn canonical_index(&self) -> usizewhere
T: Ord,
The starting index of the lexicographically smallest rotation (Booth’s algorithm, O(n)).
Returns 0 for empty or single-element sequences.
§Examples
use ring_seq::RingSeq;
assert_eq!([2, 0, 1].canonical_index(), 1);Sourcefn canonical(&self) -> Vec<T>
fn canonical(&self) -> Vec<T>
The lexicographically smallest rotation of this ring (necklace canonical form).
Two rings are rotations of each other iff their canonical forms are equal — useful for hashing and deduplicating equivalent rings.
§Examples
use ring_seq::RingSeq;
assert_eq!([2, 0, 1].canonical(), vec![0, 1, 2]);Sourcefn bracelet(&self) -> Vec<T>
fn bracelet(&self) -> Vec<T>
The lexicographically smallest representative under both rotation and reflection (bracelet canonical form).
Two rings belong to the same bracelet equivalence class iff their bracelet forms are equal — useful when mirror images are considered identical.
§Examples
use ring_seq::RingSeq;
assert_eq!([2, 1, 0].bracelet(), vec![0, 1, 2]);
assert_eq!([0, 1, 2].bracelet(), vec![0, 1, 2]);Sourcefn rotational_symmetry(&self) -> usizewhere
T: PartialEq,
fn rotational_symmetry(&self) -> usizewhere
T: PartialEq,
The order of rotational symmetry: the number of distinct rotations that map the ring onto itself.
Returns 1 for sequences with no rotational symmetry (only the identity),
and n when all elements are equal.
§Examples
use ring_seq::RingSeq;
assert_eq!([0, 1, 2, 0, 1, 2].rotational_symmetry(), 2);
assert_eq!([0, 1, 2].rotational_symmetry(), 1);
assert_eq!([5, 5, 5].rotational_symmetry(), 3);Sourcefn symmetry_indices(&self) -> Vec<usize>where
T: PartialEq,
fn symmetry_indices(&self) -> Vec<usize>where
T: PartialEq,
Indices of elements where a reflectional-symmetry axis passes nearby.
More precisely, the “shift” values for which the ring equals its reversal rotated by that shift.
§Examples
use ring_seq::RingSeq;
assert_eq!(
[2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2].symmetry_indices(),
vec![0, 3, 6, 9],
);Sourcefn reflectional_symmetry_axes(&self) -> Vec<(AxisLocation, AxisLocation)>where
T: PartialEq,
fn reflectional_symmetry_axes(&self) -> Vec<(AxisLocation, AxisLocation)>where
T: PartialEq,
Axes of reflectional symmetry, expressed as pairs of
AxisLocations where each axis intersects the ring.
§Examples
use ring_seq::{AxisLocation, RingSeq};
let axes = [0, 1, 0].reflectional_symmetry_axes();
assert_eq!(axes.len(), 1);
assert_eq!(axes[0], (AxisLocation::Vertex(1), AxisLocation::Edge(2, 0)));Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.