95 lines
1.7 KiB
Rust
Executable File
95 lines
1.7 KiB
Rust
Executable File
use std::iter::Peekable;
|
|
|
|
fn main() {
|
|
//
|
|
// println!("sum of primes less than 2,000,000 is : {}",
|
|
// PrimeItr::default()
|
|
// .take_while( |x| x < 2_000_000 )
|
|
// .sum::<usize>())
|
|
//
|
|
// println!("largest prime factor is : {}", PrimeItr::default()
|
|
// .take_while( |x| *x < 600851475143/2 )
|
|
// .filter( |x| x % 600851475143 != 0 )
|
|
// .last()
|
|
// .expect(PRIME_ERR)
|
|
// )
|
|
//
|
|
for x in PrimeFactItr::factors(600851475143) {
|
|
println!("{}", x)
|
|
}
|
|
}
|
|
|
|
const PRIME_ERR: &str = "unexpected item in bagging area";
|
|
|
|
//prime iterator
|
|
|
|
struct PrimeItr {
|
|
record: Vec<usize>,
|
|
index: usize
|
|
}
|
|
|
|
impl Iterator for PrimeItr {
|
|
type Item = usize;
|
|
fn next ( &mut self ) -> Option<usize> {
|
|
let is_prime = !self.record.iter()
|
|
.take_while( |x| **x * **x < self.index )
|
|
.any( |x| self.index % *x == 0 );
|
|
let result = self.index;
|
|
self.index += if self.index == 2 { 1 } else { 2 };
|
|
if is_prime {
|
|
self.record.push(result);
|
|
Some(result)
|
|
}
|
|
else {
|
|
self.next()
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for PrimeItr {
|
|
fn default() -> Self {
|
|
PrimeItr {
|
|
record: vec![],
|
|
index: 2
|
|
}
|
|
}
|
|
}
|
|
|
|
// prime factorization iterator
|
|
|
|
struct PrimeFactItr {
|
|
record: Vec<usize>,
|
|
chuck: usize,
|
|
prime: Peekable<PrimeItr>
|
|
}
|
|
|
|
impl Iterator for PrimeFactItr {
|
|
type Item = usize;
|
|
fn next ( &mut self ) -> Option<usize> {
|
|
let x = *self.prime.peek().expect(PRIME_ERR);
|
|
let is_factor = self.chuck % x == 0;
|
|
if is_factor {
|
|
self.record.push(x);
|
|
self.chuck /= x;
|
|
Some(x)
|
|
}
|
|
else if x > self.chuck {
|
|
None
|
|
}
|
|
else {
|
|
self.prime.next();
|
|
self.next()
|
|
}
|
|
}
|
|
}
|
|
|
|
impl PrimeFactItr {
|
|
fn factors(x: usize) -> Self {
|
|
PrimeFactItr {
|
|
record: vec![],
|
|
chuck: x,
|
|
prime: PrimeItr::default().peekable()
|
|
}
|
|
}
|
|
}
|