Skip to content

Instantly share code, notes, and snippets.

@nanpuyue
Created January 9, 2020 14:58
Show Gist options
  • Save nanpuyue/e7cd92cb28409e369d5332869f8d3fc1 to your computer and use it in GitHub Desktop.
Save nanpuyue/e7cd92cb28409e369d5332869f8d3fc1 to your computer and use it in GitHub Desktop.
// date: 2019-01-09
// license: GPLv3 https://www.gnu.org/licenses/gpl-3.0.txt
// author: nanpuyue <[email protected]> https://blog.nanpuyue.com
#![feature(generator_trait)]
use std::ops::{Generator, GeneratorState};
use std::pin::Pin;
use num_integer::Integer;
use num_traits::{Unsigned, WrappingAdd};
struct PrimeGenerator<T> {
list: Vec<T>,
last: T,
}
impl<T: Unpin + Unsigned> PrimeGenerator<T> {
fn new() -> Self {
Self {
list: Vec::new(),
last: T::one(),
}
}
}
impl<T: Copy + Unpin + Integer + Unsigned + WrappingAdd + PartialOrd> Generator
for PrimeGenerator<T>
{
type Yield = T;
type Return = ();
fn resume(self: Pin<&mut Self>) -> GeneratorState<Self::Yield, Self::Return> {
let self_inner = Pin::into_inner(self);
'outter: loop {
self_inner.last = self_inner.last.wrapping_add(&T::one());
if self_inner.last == T::zero() {
return GeneratorState::Complete(());
}
for i in self_inner.list.iter() {
let (quotient, rem) = self_inner.last.div_rem(i);
if rem == T::zero() {
continue 'outter;
}
if i > &quotient {
break;
}
}
self_inner.list.push(self_inner.last);
return GeneratorState::Yielded(self_inner.last);
}
}
}
fn main() {
let mut prime_generator = PrimeGenerator::<u8>::new();
loop {
match Pin::new(&mut prime_generator).resume() {
GeneratorState::Yielded(n) => println!("{}", n),
GeneratorState::Complete(_) => break,
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment