use std::iter::repeat_with;
use super::Sequence;
#[derive(Debug, Clone)]
pub struct Lucas {
initial_values: (u32, u32),
}
impl Lucas {
pub fn new(initial_values: (u32, u32)) -> Self {
Self { initial_values }
}
pub fn fibonacci() -> Self {
Self { initial_values: (0, 1) }
}
}
impl Sequence for Lucas {
type Term = u32;
fn terms(&self) -> Box<dyn Iterator<Item = Self::Term> + '_> {
let mut two_terms = self.initial_values;
Box::new(repeat_with(move || {
let out = two_terms.0;
let sum = two_terms.0 + two_terms.1;
two_terms.0 = two_terms.1;
two_terms.1 = sum;
out
}))
}
fn approx_num_terms(&self) -> Option<usize> {
None
}
}
#[derive(Debug, Clone)]
pub struct Collatz {
starting_element: u32,
}
impl Collatz {
pub fn new(starting_element: u32) -> Self {
Self { starting_element }
}
}
impl Sequence for Collatz {
type Term = u32;
fn terms(&self) -> Box<dyn Iterator<Item = Self::Term> + '_> {
let mut last = self.starting_element;
Box::new(std::iter::once(self.starting_element).chain(repeat_with(move || {
last = if last.is_multiple_of(2) {
last / 2
} else {
3 * last + 1
};
last
})))
}
fn approx_num_terms(&self) -> Option<usize> {
None
}
}
#[derive(Debug, Clone)]
pub struct ThueMorse {
starting_element: u32,
}
impl ThueMorse {
pub fn new(starting_element: u32) -> Self {
assert!([0, 1].contains(&starting_element), "Thue-Morse sequence starts with 0 or 1");
Self { starting_element }
}
}
impl Sequence for ThueMorse {
type Term = u32;
fn terms(&self) -> Box<dyn Iterator<Item = Self::Term> + '_> {
let starting_element = self.starting_element;
let mut cached_sequence = vec![starting_element];
Box::new(std::iter::once(starting_element).chain((1..).map(move |index| {
let new_term = if index % 2 == 0 {
cached_sequence[index/2]
} else {
1 - cached_sequence[index/2]
};
cached_sequence.push(new_term);
new_term
})))
}
fn approx_num_terms(&self) -> Option<usize> {
None
}
}