114 lines
2.8 KiB
Rust
114 lines
2.8 KiB
Rust
use std::collections::HashSet;
|
|
|
|
// you will probably need to incrase the stack limit
|
|
// $ ulimit -s
|
|
// $ ulimit -s 32768
|
|
|
|
type Int = i64;
|
|
const MIN_VALUE: Int = 2;
|
|
const MAX_VALUE: Int = 1_000_000;
|
|
const SIZE: usize = (MAX_VALUE - MIN_VALUE) as usize;
|
|
type Array = [bool; SIZE];
|
|
|
|
fn main() {
|
|
println!("Getting prime numbers up to {}", MAX_VALUE);
|
|
let primes = Primes::from_array(get_prime_numbers_array());
|
|
println!("Starting to iterate ...");
|
|
let result = find_using_iter(&primes).unwrap();
|
|
println!(
|
|
"{:?} / sum: {} / len: {}",
|
|
result,
|
|
sum_of_vector(result),
|
|
result.len()
|
|
);
|
|
}
|
|
|
|
fn get_prime_numbers_array() -> Array {
|
|
// Sieve of Eratosthenes
|
|
let mut result = [true; SIZE];
|
|
for number_to_check in MIN_VALUE..(MAX_VALUE / 2) {
|
|
let mut last_number = number_to_check;
|
|
loop {
|
|
let current_number = last_number + number_to_check;
|
|
if current_number >= MAX_VALUE {
|
|
break;
|
|
}
|
|
result[(current_number - MIN_VALUE) as usize] = false;
|
|
last_number = current_number;
|
|
}
|
|
}
|
|
result
|
|
}
|
|
|
|
fn sum_of_vector(vector: &[Int]) -> Int {
|
|
vector.iter().sum()
|
|
}
|
|
|
|
struct Primes {
|
|
vector: Vec<Int>,
|
|
set: HashSet<Int>,
|
|
}
|
|
|
|
struct PrimesIter<'a> {
|
|
primes: &'a Primes,
|
|
current_min: usize,
|
|
current_len: usize,
|
|
}
|
|
|
|
impl<'a> Iterator for PrimesIter<'a> {
|
|
type Item = &'a [Int];
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
let result = &self.primes.vector[self.current_min..(self.current_min + self.current_len)];
|
|
if result.iter().sum::<Int>() > MAX_VALUE {
|
|
self.decrement_search_length();
|
|
return self.next();
|
|
}
|
|
if self.current_min + self.current_len < self.primes.vector.len() {
|
|
self.current_min += 1;
|
|
} else {
|
|
self.decrement_search_length();
|
|
}
|
|
Some(result)
|
|
}
|
|
}
|
|
|
|
impl<'a> PrimesIter<'a> {
|
|
fn decrement_search_length(&mut self) {
|
|
self.current_min = 0;
|
|
self.current_len -= 1;
|
|
println!("{}", self.current_len);
|
|
}
|
|
}
|
|
|
|
impl Primes {
|
|
fn iter(&self) -> PrimesIter {
|
|
PrimesIter {
|
|
primes: self,
|
|
current_min: 0,
|
|
current_len: self.vector.len(),
|
|
}
|
|
}
|
|
|
|
fn from_array(array: Array) -> Primes {
|
|
let mut vector = Vec::new();
|
|
let mut set = HashSet::new();
|
|
for number in MIN_VALUE..MAX_VALUE {
|
|
if array[(number - MIN_VALUE) as usize] {
|
|
vector.push(number);
|
|
set.insert(number);
|
|
}
|
|
}
|
|
Primes { vector, set }
|
|
}
|
|
}
|
|
|
|
fn find_using_iter(primes: &'_ Primes) -> Option<&'_ [Int]> {
|
|
for subvector in primes.iter() {
|
|
if primes.set.contains(&sum_of_vector(subvector)) {
|
|
return Some(subvector);
|
|
}
|
|
}
|
|
None
|
|
}
|