use crate::math::{AsPrimitive, Number};
pub trait IsPrime {
fn is_prime(&self) -> bool;
}
impl<T: Number> IsPrime for T {
fn is_prime(&self) -> bool {
is_prime(*self)
}
}
pub fn is_prime<T: Number>(n: T) -> bool {
if n <= T::one() {
return false;
}
let mut i = T::new(2);
while i * i <= n {
if n % i == T::zero() {
return false;
}
i += T::one();
}
true
}
pub struct SieveIter {
n: usize,
nsqrt: usize,
current: usize,
nums: Vec<bool>,
}
impl SieveIter {
pub fn new<T: Number + AsPrimitive<usize>>(n: T) -> Self {
let n = n.as_primitive().max(2);
let mut is_prime = vec![true; n + 1];
is_prime[0] = false;
is_prime[1] = false;
Self {
n,
nsqrt: ((n as f64).sqrt() as usize),
nums: is_prime,
current: 2,
}
}
}
impl Iterator for SieveIter {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
if self.current > self.nsqrt {
return self
.nums
.iter()
.skip(self.current)
.position(|&x| x)
.map(|i| {
let prime = self.current + i;
self.current = prime + 1; prime
});
}
while self.current <= self.nsqrt {
let i = self.current;
self.current += 1;
if self.nums[i] {
for j in (i * i..=self.n).step_by(i) {
self.nums[j] = false;
}
return Some(i);
}
}
None
}
}
pub fn sieve<T: Number + AsPrimitive<usize>>(n: T) -> Vec<bool> {
let n = n.as_primitive().max(2);
let mut nums = vec![true; n + 1];
nums[0] = false;
nums[1] = false;
for i in 2..=((n as f64).sqrt() as usize) {
if nums[i] {
for j in (i * i..=n).step_by(i) {
nums[j] = false;
}
}
}
nums
}
pub trait Primes: Sized {
fn primes_iter(self) -> impl Iterator<Item = usize>;
fn primes(self) -> Vec<usize> {
self.primes_iter().collect()
}
}
impl<T: Number + AsPrimitive<usize>> Primes for T {
fn primes_iter(self) -> impl Iterator<Item = usize> {
SieveIter::new(self)
}
}
pub fn primes<T: Number + AsPrimitive<usize>>(n: T) -> Vec<usize> {
sieve(n)
.iter()
.enumerate()
.filter_map(|(i, &p)| if p { Some(i) } else { None })
.collect()
}
pub fn non_primes<T: Number + AsPrimitive<usize>>(n: T) -> Vec<usize> {
let primes = sieve(n);
(1..=n.as_primitive()).filter(|&x| !primes[x]).collect()
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct PrimeFactor(pub usize, pub usize);
impl From<PrimeFactor> for (usize, usize) {
fn from(factor: PrimeFactor) -> Self {
(factor.0, factor.1)
}
}
impl PrimeFactor {
pub fn new(factor: usize, count: usize) -> Self {
Self(factor, count)
}
pub fn factor(&self) -> usize {
self.0
}
pub fn count(&self) -> usize {
self.1
}
}
#[derive(Debug)]
pub struct PrimeFactorsIter {
value: usize,
factors: std::ops::RangeInclusive<usize>,
}
impl PrimeFactorsIter {
pub fn new(n: usize) -> Self {
Self {
value: n,
factors: 2..=((n as f64).sqrt() as usize),
}
}
}
impl Iterator for PrimeFactorsIter {
type Item = PrimeFactor;
fn next(&mut self) -> Option<Self::Item> {
if self.value == 1 {
return None;
}
for factor in self.factors.by_ref() {
if self.value % factor == 0 {
let mut count = 0;
while self.value % factor == 0 {
self.value /= factor;
count += 1;
}
return Some(PrimeFactor(factor, count));
}
}
if self.value > 1 {
let factor = self.value;
self.value = 1;
Some(PrimeFactor(factor, 1))
} else {
None
}
}
}
pub trait PrimeFactors: Number + AsPrimitive<usize> {
fn prime_factors_iter(self) -> PrimeFactorsIter;
fn prime_factors(self) -> Vec<PrimeFactor> {
self.prime_factors_iter().collect()
}
fn max_prime_factors(self) -> Vec<usize> {
let n = self.as_primitive();
assert!(
n <= 10_000,
"n must be less than 10,000 to avoid excessive time complexity"
);
let mut nums = vec![0; n + 1];
for i in 2..=n {
if nums[i] == 0 {
for j in (i..=n).step_by(i) {
nums[j] = i;
}
}
}
nums
}
fn count_prime_factors(self) -> Vec<usize> {
let n = self.as_primitive();
let mut nums = vec![0; n + 1];
for i in 2..=n {
if nums[i] == 0 {
for j in (i..=n).step_by(i) {
nums[j] += 1;
}
}
}
nums
}
}
impl<T: Number + AsPrimitive<usize>> PrimeFactors for T {
fn prime_factors_iter(self) -> PrimeFactorsIter {
PrimeFactorsIter::new(self.as_primitive())
}
}
pub fn factorize(n: usize) -> Vec<PrimeFactor> {
PrimeFactorsIter::new(n).collect()
}
pub trait Factors: Number + AsPrimitive<usize> {
fn factors(self) -> Vec<usize> {
factors(self.as_primitive())
}
}
impl<T: Number + AsPrimitive<usize>> Factors for T {}
pub fn factors(n: usize) -> Vec<usize> {
generate_divisors(factorize(n))
}
fn generate_divisors(factors: Vec<PrimeFactor>) -> Vec<usize> {
let factor_powers: Vec<Vec<_>> = factors
.into_iter()
.map(Into::into)
.map(|(factor, cnt)| (0..=cnt).map(|i| factor.pow(i as u32)).collect::<Vec<_>>())
.collect();
generate_combinations(&factor_powers, 0, 1)
}
fn generate_combinations(factor_powers: &Vec<Vec<usize>>, i: usize, product: usize) -> Vec<usize> {
if i == factor_powers.len() {
vec![product]
} else {
let mut result = vec![];
for &power in &factor_powers[i] {
result.extend(generate_combinations(factor_powers, i + 1, product * power));
}
result
}
}
#[cfg(test)]
mod tests {
use {super::*, crate::ext::vec::sorted::Sorted};
#[test]
fn test_is_prime() {
let primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29];
let non_primes = [
0, 1, 4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22, 24, 25, 26, 27, 28,
];
assert!(primes.iter().all(|&x| is_prime(x)));
assert!(primes.iter().all(|&x| x.is_prime()));
assert!(non_primes.iter().all(|&x| !is_prime(x)));
assert!(non_primes.iter().all(|&x| !x.is_prime()));
}
#[test]
fn test_sieve() {
let primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29];
let n = 30;
let sieve = sieve(n);
for i in 0..n {
assert_eq!(sieve[i], primes.contains(&i));
}
}
#[test]
fn sieve_iter() {
let iter = SieveIter::new(30);
let primes: Vec<_> = iter.collect();
assert_eq!(primes, vec![2, 3, 5, 7, 11, 13, 17, 19, 23, 29]);
}
#[test]
fn test_max_factors() {
assert_eq!(30.max_prime_factors(), [
0, 0, 2, 3, 2, 5, 3, 7, 2, 3, 5, 11, 3, 13, 7, 5, 2, 17, 3, 19, 5, 7, 11, 23, 3, 5, 13,
3, 7, 29, 5
]);
}
#[test]
fn test_count_factors() {
assert_eq!(30.count_prime_factors(), [
0, 0, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 2, 1, 2, 2, 1, 1, 2, 1, 2, 2, 2, 1, 2, 1, 2, 1, 2,
1, 3
]);
}
#[test]
fn test_factorize() {
assert_eq!(factorize(30), vec![
PrimeFactor(2, 1),
PrimeFactor(3, 1),
PrimeFactor(5, 1),
]);
assert_eq!(factorize(60), vec![
PrimeFactor(2, 2),
PrimeFactor(3, 1),
PrimeFactor(5, 1),
]);
assert_eq!(factorize(90), vec![
PrimeFactor(2, 1),
PrimeFactor(3, 2),
PrimeFactor(5, 1),
]);
}
#[test]
fn test_prime_factors_iter() {
let mut factors = PrimeFactorsIter::new(30);
assert_eq!(factors.next(), Some(PrimeFactor(2, 1)));
assert_eq!(factors.next(), Some(PrimeFactor(3, 1)));
assert_eq!(factors.next(), Some(PrimeFactor(5, 1)));
assert_eq!(factors.next(), None);
let mut factors = PrimeFactorsIter::new(60);
assert_eq!(factors.next(), Some(PrimeFactor(2, 2)));
assert_eq!(factors.next(), Some(PrimeFactor(3, 1)));
assert_eq!(factors.next(), Some(PrimeFactor(5, 1)));
assert_eq!(factors.next(), None);
let mut factors = PrimeFactorsIter::new(90);
assert_eq!(factors.next(), Some(PrimeFactor(2, 1)));
assert_eq!(factors.next(), Some(PrimeFactor(3, 2)));
assert_eq!(factors.next(), Some(PrimeFactor(5, 1)));
assert_eq!(factors.next(), None);
}
#[test]
fn test_all_divisors() {
assert_eq!(30.factors().sorted(), vec![1, 2, 3, 5, 6, 10, 15, 30]);
assert_eq!(60.factors().sorted(), vec![
1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60
]);
assert_eq!(90.factors().sorted(), vec![
1, 2, 3, 5, 6, 9, 10, 15, 18, 30, 45, 90
]);
assert_eq!(1.factors(), vec![1]);
}
#[test]
fn test_big_prime() {
assert!(is_prime(1_000_000_007));
let factors = factorize(1_000_000_000);
assert_eq!(factors, vec![PrimeFactor(2, 9), PrimeFactor(5, 9),]);
let divs = 1_000_000_000.factors();
assert_eq!(divs.len(), 100);
}
}