1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
use rational_sequences::{rational_sequence_reduce, RationalSequence};
use std::ops::Index;
impl<T: Eq> Index<usize> for RationalSequence<T> {
type Output = T;
/// Gets a reference to an element of a [`RationalSequence`] at an index.
///
/// If the index is greater than or equal to the length of the sequence, this function panics.
///
/// # Worst-case complexity
/// Constant time and additional memory.
///
/// # Panics
/// Panics if `index` is greater than or equal to the length of this sequence.
///
/// # Examples
/// ```
/// use malachite_base::rational_sequences::RationalSequence;
///
/// assert_eq!(RationalSequence::from_slices(&[1, 2], &[3, 4])[1], 2);
/// assert_eq!(RationalSequence::from_slices(&[1, 2], &[3, 4])[10], 3);
/// ```
#[inline]
fn index(&self, i: usize) -> &T {
self.get(i).unwrap()
}
}
impl<T: Eq> RationalSequence<T> {
/// Gets a reference to an element of a [`RationalSequence`] at an index.
///
/// If the index is greater than or equal to the length of the sequence, `None` is returned.
///
/// # Worst-case complexity
/// Constant time and additional memory.
///
/// # Examples
/// ```
/// use malachite_base::rational_sequences::RationalSequence;
///
/// assert_eq!(RationalSequence::from_slices(&[1, 2], &[3, 4]).get(1), Some(&2));
/// assert_eq!(RationalSequence::from_slices(&[1, 2], &[3, 4]).get(10), Some(&3));
/// ```
pub fn get(&self, i: usize) -> Option<&T> {
let non_repeating_len = self.non_repeating.len();
if i < non_repeating_len {
Some(&self.non_repeating[i])
} else if self.repeating.is_empty() {
None
} else {
Some(&self.repeating[(i - non_repeating_len) % self.repeating.len()])
}
}
}
impl<T: Clone + Eq> RationalSequence<T> {
/// Mutates an element of a [`RationalSequence`] at an index using a provided closure, and then
/// returns whatever the closure returns.
///
/// If the index is greater than or equal to the length of the sequence, this function panics.
///
/// # Worst-case complexity
/// $T(n) = O(n)$
///
/// $M(n) = O(n)$
///
/// where $T$ is time, $M$ is additional memory, and $n$ is `index`.
///
/// # Panics
/// Panics if `index` is greater than or equal to the length of this sequence.
///
/// # Examples
/// ```
/// use malachite_base::rational_sequences::RationalSequence;
///
/// let mut xs = RationalSequence::from_slices(&[1, 2], &[3, 4]);
/// assert_eq!(xs.mutate(1, |x| { *x = 100; 25 }), 25);
/// assert_eq!(xs, RationalSequence::from_slices(&[1, 100], &[3, 4]));
///
/// let mut xs = RationalSequence::from_slices(&[1, 2], &[3, 4]);
/// assert_eq!(xs.mutate(6, |x| { *x = 100; 25 }), 25);
/// assert_eq!(xs, RationalSequence::from_slices(&[1, 2, 3, 4, 3, 4, 100], &[4, 3]));
/// ```
pub fn mutate<F: FnOnce(&mut T) -> U, U>(&mut self, i: usize, f: F) -> U {
let non_repeating_len = self.non_repeating.len();
let result = if i < non_repeating_len {
f(&mut self.non_repeating[i])
} else if self.repeating.is_empty() {
panic!("index out of bounds");
} else {
let repeating_len = self.repeating.len();
let extra = i - non_repeating_len + 1;
self.non_repeating
.extend(self.repeating.iter().cycle().take(extra).cloned());
self.repeating.rotate_left(extra % repeating_len);
f(&mut self.non_repeating[i])
};
rational_sequence_reduce(&mut self.non_repeating, &mut self.repeating);
result
}
}