use crate::core::{MomaRing, OriginStrategy};
use crate::primes;
use std::marker::PhantomData;
pub type PrimePropertyFn = fn(u64) -> u64;
pub struct ResonanceFinder<S: OriginStrategy> {
ring: MomaRing<S>,
property_fn: PrimePropertyFn,
_strategy: PhantomData<S>,
}
impl<S: OriginStrategy> ResonanceFinder<S> {
pub fn new(modulus: u64, strategy: S, property_fn: PrimePropertyFn) -> Self {
Self {
ring: MomaRing::new(modulus, strategy),
property_fn,
_strategy: PhantomData,
}
}
pub fn check_prime(&self, p: u64) -> Option<u64> {
let signature = self.ring.signature(p);
let property_value = (self.property_fn)(p);
if property_value > 0 && signature % property_value == 0 {
Some(signature)
} else {
None
}
}
pub fn find_in_range(&self, start_range: u64, end_range: u64) -> Vec<(u64, u64)> {
let mut p = primes::next_prime(start_range.saturating_sub(1));
let mut resonances = Vec::new();
while p < end_range {
if let Some(signature) = self.check_prime(p) {
resonances.push((p, signature));
}
p = primes::next_prime(p);
}
resonances
}
}