KOISBSJ3KKEP44EXD6CC3NVTTQLLOBZDONMHTVLGOSTDXUD6SJTQC
SPUEEQZQFZDVOLZTAXLRHXPCQ3JWN32O7YCND24XVCHYIDNNT4QQC
YGJVWTKAANDS6TUXWRI5V4TLVWTZNBNX2HXRYJ2WSPBPI2U6MB2AC
QK6XE5XFT6XT6N2TAFLZTJAV3FWDDWXMXHHEE7MCFIUBRETV2HFQC
JZN2AQ3EMSXVYKPYPMHKN6JFKAFGZMQLHO7N5A37SKTNFWFI53OQC
ERYD4CD76UGRWQJXSVEPME4XJNQOGECALQEB3NBE76RLJX22TX6AC
KWE5K6XLZULD6MDDVM7X2YFMYMKL76L4MHRAUXZ6EWL5YAJVBKUQC
XDEY7SNLZMAC3KIKUHDGZGGXHHT7BYF3GSVAREXESO5D4S6FZBQQC
UTP7D53QIV7KUBI3DX36GSDXMSAVIMDSPOSYN7SJEREOHBHJIEKAC
IXMBS6ZPQSFG6HTYGHNJJ3YK2KYGUBBNTMIU7Q5CAKLJEXSBP4EAC
impl<A: std::fmt::Debug> fmt::Display for CreationError<A> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CreationError::SubsetBiggerThanSet { set, subset_size } => write!(
f,
"Subset can't be bigger than set.\nset: {:?}\nsubset_size: {:?}",
set, subset_size
),
}
impl<A: std::fmt::Debug> fmt::Display for CreationError<A> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CreationError::SubsetBiggerThanSet { set, subset_size } => write!(
f,
"Subset can't be bigger than set.\nset: {:?}\nsubset_size: {:?}",
set, subset_size
),
pub struct CombinationsWithoutReplacement<'a, A>
where
A: Clone,
{
set: &'a [A],
subset_indices: Vec<usize>,
index: usize,
state: State,
}
/// Generates combinations of elements of a set without replacement/repetition of the elements.
/// Implements the [Revolving Door algorithm](http://math0.wvstateu.edu/~baker/cs405/code/RevolvingDoor.html).
struct CombinationsWithoutReplacement<'a, A>
where
A: Clone,
{
set: &'a [A],
subset_indices: Vec<usize>,
index: usize,
state: State,
}
impl<A> CombinationsWithoutReplacement<'_, A>
where
A: Clone,
{
// R1: Initialise
pub fn new(
set: &[A],
subset_size: usize,
) -> Result<CombinationsWithoutReplacement<A>, CreationError<A>> {
if set.len() < subset_size {
Err(CreationError::SubsetBiggerThanSet {
set: set.to_owned(),
subset_size,
})
} else {
Ok(CombinationsWithoutReplacement {
set,
subset_indices: {
let mut a: Vec<usize> = Vec::with_capacity(subset_size + 1);
for b in 0..subset_size {
a.push(b);
}
a.push(set.len());
a
},
index: 0,
state: State::A,
})
}
impl<A> CombinationsWithoutReplacement<'_, A>
where
A: Clone,
{
// R1: Initialise
/// # Arguments
///
/// * `set`: Set to generate combinations of.
/// * `subset_size`: Size of subsets containing the combinations to output.
fn new(
set: &[A],
subset_size: usize,
) -> Result<CombinationsWithoutReplacement<A>, CreationError<A>> {
if set.len() < subset_size {
Err(CreationError::SubsetBiggerThanSet {
set: set.to_owned(),
subset_size,
})
} else {
Ok(CombinationsWithoutReplacement {
set,
subset_indices: {
let mut a: Vec<usize> = Vec::with_capacity(subset_size + 1);
for b in 0..subset_size {
a.push(b);
}
a.push(set.len());
a
},
index: 0,
state: State::A,
})
// R2: State::A
fn visit(&mut self) -> Option<Vec<A>> {
match self.subset_indices.len() - 1 {
0 => Some(vec![]),
1 => {
self.index += 1;
if self.index > self.set.len() {
self.state = State::E;
None
} else {
Some(vec![self.set[self.index - 1].clone()])
}
}
index if index == self.set.len() => {
// R2: State::A
fn visit(&mut self) -> Option<Vec<A>> {
match self.subset_indices.len() - 1 {
0 => Some(vec![]),
1 => {
self.index += 1;
if self.index > self.set.len() {
// R3: State::B
fn easy_cases(&mut self) {
if (self.subset_indices.len() - 1) & 1 == 1 {
if self.subset_indices[0] + 1 < self.subset_indices[1] {
self.subset_indices[0] += 1;
self.state = State::A;
} else {
self.index = 1;
self.state = State::C;
}
} else if self.subset_indices[0] > 0 {
self.subset_indices[0] -= 1;
// R3: State::B
fn easy_cases(&mut self) {
if (self.subset_indices.len() - 1) & 1 == 1 {
if self.subset_indices[0] + 1 < self.subset_indices[1] {
self.subset_indices[0] += 1;
// R4: State::C
fn try_to_decrease_at_index(&mut self) {
if self.subset_indices[self.index] > self.index {
self.subset_indices[self.index] = self.subset_indices[self.index - 1];
self.subset_indices[self.index - 1] = self.index - 1;
self.state = State::A;
} else {
self.index += 1;
self.state = State::D;
}
// R4: State::C
fn try_to_decrease_at_index(&mut self) {
if self.subset_indices[self.index] > self.index {
self.subset_indices[self.index] = self.subset_indices[self.index - 1];
self.subset_indices[self.index - 1] = self.index - 1;
self.state = State::A;
} else {
self.index += 1;
self.state = State::D;
// R5: State::D
fn try_to_increase_at_index(&mut self) {
if self.subset_indices[self.index] + 1 < self.subset_indices[self.index + 1] {
self.subset_indices[self.index - 1] = self.subset_indices[self.index];
self.subset_indices[self.index] += 1;
self.state = State::A;
// R5: State::D
fn try_to_increase_at_index(&mut self) {
if self.subset_indices[self.index] + 1 < self.subset_indices[self.index + 1] {
self.subset_indices[self.index - 1] = self.subset_indices[self.index];
self.subset_indices[self.index] += 1;
self.state = State::A;
} else {
self.index += 1;
if self.index < (self.subset_indices.len() - 1) {
self.state = State::C;
fn next(&mut self) -> Option<Self::Item> {
match self.state {
State::A => self.visit(),
State::E => None,
_ => {
while self.state != State::A && self.state != State::E {
match self.state {
State::B => self.easy_cases(),
State::C => self.try_to_decrease_at_index(),
State::D => self.try_to_increase_at_index(),
_ => (),
}
fn next(&mut self) -> Option<Self::Item> {
match self.state {
State::A => self.visit(),
State::E => None,
_ => {
while self.state != State::A && self.state != State::E {
match self.state {
State::B => self.easy_cases(),
State::C => self.try_to_decrease_at_index(),
State::D => self.try_to_increase_at_index(),
_ => (),
mod multiples {
use crate::num_traits::Unsigned;
#[derive(Debug)]
pub struct UnsignedMultiples<A>
where
A: Copy + Unsigned,
{
factor: A,
limit: A,
out: A,
}
impl<A> UnsignedMultiples<A>
where
A: Copy + Unsigned,
{
pub fn new(factor: A, limit: A) -> UnsignedMultiples<A> {
UnsignedMultiples {
factor,
limit,
out: factor,
}
impl<A> UnsignedMultiples<A>
where
A: Copy + Unsigned,
{
/// # Arguments
///
/// * `factor`: Number to generate multiples of.
/// * `limit`: Number at which no more multiples will be generated.
fn new(factor: A, limit: A) -> UnsignedMultiples<A> {
UnsignedMultiples {
factor,
limit,
out: factor,
impl<A> Iterator for UnsignedMultiples<A>
where
A: core::ops::AddAssign + core::ops::Sub<Output = A> + Copy + PartialOrd + Unsigned,
{
type Item = A;
impl<A> Iterator for UnsignedMultiples<A>
where
A: core::ops::AddAssign + core::ops::Sub<Output = A> + Copy + PartialOrd + Unsigned,
{
type Item = A;
fn next(&mut self) -> Option<Self::Item> {
if self.out < self.limit {
self.out += self.factor;
Some(self.out - self.factor)
} else {
None
}
fn next(&mut self) -> Option<Self::Item> {
if self.out < self.limit {
let out = self.out;
self.out += self.factor;
Some(out)
} else {
None
.filter(|factor| *factor != 0)
.collect::<Vec<u32>>();
if factors.is_empty() {
.filter(|&factor| factor != 0)
.for_each(|factor| {
if done.iter().all(|&done_factor| factor % done_factor != 0) {
out.push(factor);
}
done.push(factor);
});
if out.is_empty() {
// Approximated size of the list required using the inverse of an approximation of the prime-counting function, halved (as we're only interested in odd numbers).
let list_size = (corrected_n * (corrected_n * corrected_n.ln()).ln() / 2.0) as usize + 1;
// Approximated size of the list required using the inverse of an approximation of the prime-counting function, halved (as we're only interested in odd numbers). Lossy cast.
let list_size = (corrected_n * (corrected_n * corrected_n.ln()).ln() / 2.0).ceil() as usize;