use std::collections::HashMap;
pub fn is_prime(n: u64) -> bool {
let mut result = true;
if n < 2 {
result = false;
} else if n == 2 || n == 3 {
result = true;
} else if n.is_multiple_of(2) {
result = false;
} else {
let mut i = 3;
while i * i <= n {
if n.is_multiple_of(i) {
result = false;
break;
}
i += 2;
}
}
result
}
pub fn is_prime_miller_rabin(n: u64) -> bool {
let mut result = true;
if n < 2 {
result = false;
} else {
let small_primes: [u64; 12] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37];
let mut divisible_by_small = false;
for &p in &small_primes {
if n == p {
divisible_by_small = true;
result = true;
break;
}
if n.is_multiple_of(p) {
divisible_by_small = true;
result = false;
break;
}
}
if !divisible_by_small {
let mut d = n - 1;
let mut s = 0;
while d.is_multiple_of(2) {
d /= 2;
s += 1;
}
let witnesses: [u64; 12] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37];
let mut composite = false;
for &a in &witnesses {
if a >= n {
continue;
}
let mut x = mod_pow(a, d, n);
if x == 1 || x == n - 1 {
continue;
}
let mut witness_passed = false;
for _ in 0..(s - 1) {
x = mul_mod(x, x, n);
if x == n - 1 {
witness_passed = true;
break;
}
}
if !witness_passed {
composite = true;
break;
}
}
result = !composite;
}
}
result
}
fn mul_mod(a: u64, b: u64, m: u64) -> u64 {
((a as u128) * (b as u128) % (m as u128)) as u64
}
pub fn pollard_rho(n: u64, seed: u64) -> Option<u64> {
if n.is_multiple_of(2) {
return Some(2);
}
if is_prime_miller_rabin(n) {
return None;
}
let f = |x: u64| mul_mod(x, x, n).wrapping_add(seed) % n;
let mut x = 2u64;
let mut y = 2u64;
let mut d = 1u64;
while d == 1 {
x = f(x);
y = f(f(y));
let diff = x.abs_diff(y);
d = gcd(diff, n);
}
if d == n {
None
} else {
Some(d)
}
}
pub fn gcd(mut a: u64, mut b: u64) -> u64 {
while b != 0 {
let t = b;
b = a % b;
a = t;
}
a
}
pub fn factor_advanced(n: u64) -> HashMap<u64, u32> {
let mut factors = HashMap::new();
let mut n = n;
let small_primes = sieve_primes(10000);
for &p in &small_primes {
if p * p > n {
break;
}
while n.is_multiple_of(p) {
*factors.entry(p).or_insert(0) += 1;
n /= p;
}
}
let mut stack = vec![n];
while let Some(m) = stack.pop() {
if m == 1 {
continue;
}
if is_prime_miller_rabin(m) {
*factors.entry(m).or_insert(0) += 1;
continue;
}
let mut found = false;
for seed in 1..=10 {
if let Some(d) = pollard_rho(m, seed) {
stack.push(d);
stack.push(m / d);
found = true;
break;
}
}
if !found {
let tf = factor_trial(m);
for (p, exp) in tf {
*factors.entry(p).or_insert(0) += exp;
}
}
}
factors
}
pub fn factor_quadratic_sieve(n: u64) -> Option<HashMap<u64, u32>> {
if n < 2 {
return None;
}
if n.is_multiple_of(2) {
let mut result = HashMap::new();
result.insert(2, 1);
if let Some(rest) = factor_quadratic_sieve(n / 2) {
for (p, e) in rest {
*result.entry(p).or_insert(0) += e;
}
}
return Some(result);
}
let nf = n as f64;
let ln_n = nf.ln();
let ln_ln_n = ln_n.ln();
let b_est = (0.5 * (ln_n * ln_ln_n).sqrt()).exp() as usize;
let b = b_est.clamp(10, 1000);
let primes = sieve_primes(b);
let mut factor_base: Vec<u64> = Vec::new();
for &p in &primes {
if p == 2 {
continue;
}
if legendre_symbol(n, p) == 1 || n.is_multiple_of(p) {
factor_base.push(p);
}
}
if factor_base.is_empty() {
return Some(factor_trial(n));
}
let m = (nf.sqrt().floor() as u64) + 1;
let sieve_range = 10000usize; let mut relations: Vec<(u64, Vec<u32>)> = Vec::new();
for i in 0..sieve_range {
let x = m + i as u64;
let y = if x * x > n { (x * x) % n } else { x * x };
let _y_f = y as f64;
let mut exponents = vec![0u32; factor_base.len()];
let mut remaining = y;
let mut _is_smooth = true;
for (j, &p) in factor_base.iter().enumerate() {
while remaining % p == 0 {
remaining /= p;
exponents[j] += 1;
}
}
if remaining == 1 {
relations.push((x, exponents));
}
if relations.len() >= factor_base.len() + 5 {
break;
}
}
if relations.len() < factor_base.len() {
return Some(factor_advanced(n));
}
let mut rng_seed = 1u64;
for _ in 0..1000 {
rng_seed = rng_seed.wrapping_mul(1103515245).wrapping_add(12345);
let mask = rng_seed;
let mut combined_exp = vec![0u32; factor_base.len()];
let mut x_product = 1u64;
let mut count = 0u32;
for (i, (x, exp)) in relations.iter().enumerate() {
if (mask >> (i % 64)) & 1 == 1 {
for j in 0..factor_base.len() {
combined_exp[j] += exp[j];
}
x_product = mul_mod(x_product, *x, n);
count += 1;
}
}
let all_even = combined_exp.iter().all(|&e| e % 2 == 0);
if all_even && count > 0 {
let mut y_sqrt = 1u64;
for (j, &p) in factor_base.iter().enumerate() {
let half_exp = combined_exp[j] / 2;
for _ in 0..half_exp {
y_sqrt = mul_mod(y_sqrt, p, n);
}
}
let diff = x_product.abs_diff(y_sqrt);
let factor1 = gcd(diff, n);
if factor1 > 1 && factor1 < n {
let mut result = HashMap::new();
let factor2 = n / factor1;
if is_prime_miller_rabin(factor1) {
result.insert(factor1, 1);
} else if let Some(sub) = factor_quadratic_sieve(factor1) {
for (p, e) in sub {
*result.entry(p).or_insert(0) += e;
}
}
if is_prime_miller_rabin(factor2) {
result.insert(factor2, 1);
} else if let Some(sub) = factor_quadratic_sieve(factor2) {
for (p, e) in sub {
*result.entry(p).or_insert(0) += e;
}
}
return Some(result);
}
}
}
Some(factor_advanced(n))
}
pub fn factor_ecm(n: u64) -> Option<HashMap<u64, u32>> {
if n < 2 {
return None;
}
if n.is_multiple_of(2) {
let mut result = HashMap::new();
result.insert(2, 1);
if let Some(rest) = factor_ecm(n / 2) {
for (p, e) in rest {
*result.entry(p).or_insert(0) += e;
}
}
return Some(result);
}
for curve_seed in 1..=50 {
let a = (curve_seed * 1234567 + 1) % n;
let x = (curve_seed * 7654321 + 2) % n;
let y = (curve_seed * 9876543 + 3) % n;
let _b = if let Some(b_val) = mod_sub(
mul_mod(y, y, n),
add_mod(mul_mod(mul_mod(x, x, n), x, n), mul_mod(a, x, n), n),
n,
) {
b_val
} else {
continue;
};
let b1 = if n < 10000 {
100
} else if n < 1000000 {
1000
} else {
10000
};
let primes = sieve_primes(b1 as usize);
let mut k = 1u64;
for &p in &primes {
if p == 0 {
continue;
}
let mut pp = p;
while pp * p <= b1 as u64 {
pp *= p;
}
k = mul_mod(k, pp, n);
}
let mut px = x;
let mut py = y;
let mut qx = 0u64; let mut qy = 0u64;
let mut kk = k;
while kk > 0 {
if kk % 2 == 1 {
if qx == 0 && qy == 0 {
qx = px;
qy = py;
} else {
let (rx, ry, success) = ec_add(qx, qy, px, py, a, n);
if !success {
let factor = gcd(rx, n);
if factor > 1 && factor < n {
let mut result = HashMap::new();
let other = n / factor;
if is_prime_miller_rabin(factor) {
result.insert(factor, 1);
} else if let Some(sub) = factor_ecm(factor) {
for (p, e) in sub {
*result.entry(p).or_insert(0) += e;
}
}
if is_prime_miller_rabin(other) {
result.insert(other, 1);
} else if let Some(sub) = factor_ecm(other) {
for (p, e) in sub {
*result.entry(p).or_insert(0) += e;
}
}
return Some(result);
}
break;
}
qx = rx;
qy = ry;
}
}
let (rx, ry, success) = ec_double(px, py, a, n);
if !success {
let factor = gcd(rx, n);
if factor > 1 && factor < n {
let mut result = HashMap::new();
let other = n / factor;
if is_prime_miller_rabin(factor) {
result.insert(factor, 1);
} else if let Some(sub) = factor_ecm(factor) {
for (p, e) in sub {
*result.entry(p).or_insert(0) += e;
}
}
if is_prime_miller_rabin(other) {
result.insert(other, 1);
} else if let Some(sub) = factor_ecm(other) {
for (p, e) in sub {
*result.entry(p).or_insert(0) += e;
}
}
return Some(result);
}
break;
}
px = rx;
py = ry;
kk /= 2;
}
}
Some(factor_advanced(n))
}
fn ec_add(px: u64, py: u64, qx: u64, qy: u64, a: u64, n: u64) -> (u64, u64, bool) {
let _ = a;
if px == qx && py == qy {
return ec_double(px, py, a, n);
}
if px == qx {
return (0, 0, true);
}
let num = if qy >= py { qy - py } else { qy + n - py };
let den = if qx >= px { qx - px } else { qx + n - px };
let inv_den = match mod_inverse(den, n) {
Some(inv) => inv,
None => return (den, 0, false), };
let lambda = mul_mod(num, inv_den, n);
let lambda_sq = mul_mod(lambda, lambda, n);
let rx = if lambda_sq >= px + qx {
lambda_sq - px - qx
} else {
lambda_sq + n - ((px + qx) % n)
};
let rx = rx % n;
let diff = if px >= rx { px - rx } else { px + n - rx };
let ry_term = mul_mod(lambda, diff, n);
let ry = if ry_term >= py {
ry_term - py
} else {
ry_term + n - py
};
let ry = ry % n;
(rx, ry, true)
}
fn ec_double(px: u64, py: u64, a: u64, n: u64) -> (u64, u64, bool) {
if py == 0 {
return (0, 0, true); }
let x_sq = mul_mod(px, px, n);
let three_x_sq = mul_mod(3, x_sq, n);
let num = add_mod(three_x_sq, a, n);
let den = mul_mod(2, py, n);
let inv_den = match mod_inverse(den, n) {
Some(inv) => inv,
None => return (den, 0, false), };
let lambda = mul_mod(num, inv_den, n);
let lambda_sq = mul_mod(lambda, lambda, n);
let two_px = mul_mod(2, px, n);
let rx = if lambda_sq >= two_px {
lambda_sq - two_px
} else {
lambda_sq + n - two_px
};
let rx = rx % n;
let diff = if px >= rx { px - rx } else { px + n - rx };
let ry_term = mul_mod(lambda, diff, n);
let ry = if ry_term >= py {
ry_term - py
} else {
ry_term + n - py
};
let ry = ry % n;
(rx, ry, true)
}
fn add_mod(a: u64, b: u64, m: u64) -> u64 {
((a as u128 + b as u128) % (m as u128)) as u64
}
fn mod_sub(a: u64, b: u64, m: u64) -> Option<u64> {
if m == 0 {
return None;
}
Some(((a as u128 + m as u128 - (b % m) as u128) % (m as u128)) as u64)
}
pub fn sieve_primes(n: usize) -> Vec<u64> {
let mut is_prime = vec![true; n + 1];
is_prime[0] = false;
is_prime[1] = false;
for i in 2..=((n as f64).sqrt() as usize) {
if is_prime[i] {
let mut j = i * i;
while j <= n {
is_prime[j] = false;
j += i;
}
}
}
is_prime
.iter()
.enumerate()
.filter(|(_, &p)| p)
.map(|(i, _)| i as u64)
.collect()
}
pub fn nth_prime(n: usize) -> u64 {
if n == 0 {
return 0;
}
let estimate = if n < 6 {
15
} else {
let nf = n as f64;
(nf * (nf.ln() + nf.ln().ln()) * 1.5) as usize + 100
};
let primes = sieve_primes(estimate);
primes[n - 1]
}
pub fn factor_trial(n: u64) -> HashMap<u64, u32> {
let mut factors = HashMap::new();
let mut n = n;
let mut p = 2;
while p * p <= n {
while n.is_multiple_of(p) {
*factors.entry(p).or_insert(0) += 1;
n /= p;
}
p += if p == 2 { 1 } else { 2 };
}
if n > 1 {
*factors.entry(n).or_insert(0) += 1;
}
factors
}
pub fn is_semiprime(n: u64) -> bool {
let factors = factor_trial(n);
factors.values().sum::<u32>() == 2
}
pub fn semiprime_factors(n: u64) -> Option<(u64, u64)> {
let factors = factor_trial(n);
if factors.values().sum::<u32>() != 2 {
return None;
}
let mut result = Vec::new();
for (p, exp) in factors {
for _ in 0..exp {
result.push(p);
}
}
if result.len() == 2 {
Some((result[0], result[1]))
} else {
None
}
}
pub fn factor_semiprime_pi_family(n: u64, window: u64) -> Option<(u64, u64)> {
let pi = std::f64::consts::PI;
let p_est = ((n as f64) / pi).sqrt();
let p_floor = p_est as u64;
let start = if p_floor > window {
p_floor - window
} else {
2
};
let end = p_floor + window;
for p in start..=end {
if n.is_multiple_of(p) {
let q = n / p;
if p * q == n && p > 1 && q > 1 {
return Some((p, q));
}
}
}
None
}
pub fn semiprime_pi_ratio(n: u64) -> Option<f64> {
let (p, q) = semiprime_factors(n)?;
let (p, q) = if p < q { (p, q) } else { (q, p) };
Some(q as f64 / p as f64)
}
pub fn zeta_real(s: f64, terms: usize) -> f64 {
if s <= 1.0 {
return f64::NAN;
}
let mut sum = 0.0;
for n in 1..=terms {
sum += 1.0 / (n as f64).powf(s);
}
sum
}
pub fn logarithmic_integral(x: f64) -> f64 {
if x <= 1.0 {
return 0.0;
}
let n = 10000;
let a = 1.0 + 1e-10; let b = x;
let h = (b - a) / n as f64;
let mut sum = 0.5 * (1.0 / a.ln() + 1.0 / b.ln());
for i in 1..n {
let t = a + i as f64 * h;
sum += 1.0 / t.ln();
}
sum * h
}
pub fn zeta_zero_approx(n: u64) -> f64 {
if n == 0 {
return 0.0;
}
let nf = n as f64;
2.0 * std::f64::consts::PI * nf / nf.ln()
}
pub fn zeta_zero_count_approx(t: f64) -> f64 {
if t <= 0.0 {
return 0.0;
}
let t_norm = t / (2.0 * std::f64::consts::PI);
t_norm * t_norm.ln() - t_norm
}
pub fn continued_fraction(x: f64, max_terms: usize) -> Vec<(u64, u64)> {
let mut convergents = Vec::new();
let mut x = x;
let mut a0 = x as u64;
let mut p0 = a0;
let mut q0 = 1;
convergents.push((p0, q0));
if (x - a0 as f64).abs() < 1e-15 {
return convergents;
}
let mut p1 = 1;
let mut q1 = 0;
for _ in 1..max_terms {
x = 1.0 / (x - a0 as f64);
if !x.is_finite() {
break;
}
a0 = x as u64;
let p2 = a0 * p0 + p1;
let q2 = a0 * q0 + q1;
convergents.push((p2, q2));
p1 = p0;
q1 = q0;
p0 = p2;
q0 = q2;
}
convergents
}
pub fn best_rational_approx(x: f64, max_den: u64) -> (u64, u64) {
let conv = continued_fraction(x, 50);
let mut best = conv[0];
for (p, q) in conv {
if q > max_den {
break;
}
best = (p, q);
}
best
}
pub fn mod_pow(mut a: u64, mut b: u64, m: u64) -> u64 {
if m == 1 {
return 0;
}
let mut result = 1;
a %= m;
while b > 0 {
if b % 2 == 1 {
result = (result * a) % m;
}
a = (a * a) % m;
b /= 2;
}
result
}
pub fn mod_inverse(a: u64, m: u64) -> Option<u64> {
let (mut t, mut new_t) = (0i64, 1i64);
let (mut r, mut new_r) = (m as i64, a as i64);
while new_r != 0 {
let quotient = r / new_r;
let tmp_t = t - quotient * new_t;
t = new_t;
new_t = tmp_t;
let tmp_r = r - quotient * new_r;
r = new_r;
new_r = tmp_r;
}
if r > 1 {
return None;
}
if t < 0 {
t += m as i64;
}
Some(t as u64)
}
pub fn legendre_symbol(a: u64, p: u64) -> i32 {
if p == 2 {
return 1;
}
let a = a % p;
if a == 0 {
return 0;
}
let result = mod_pow(a, (p - 1) / 2, p);
if result == 1 {
1
} else {
-1
}
}
pub fn riemann_siegel_theta(t: f64) -> f64 {
if t <= 0.0 {
return 0.0;
}
let t2 = t / 2.0;
t2 * (t2 / std::f64::consts::PI).ln() - t2 - std::f64::consts::PI / 8.0 + 1.0 / (48.0 * t)
}
pub fn riemann_siegel_z(t: f64, _terms: usize) -> f64 {
if t <= 0.0 {
return 0.0;
}
let n = ((t / (2.0 * std::f64::consts::PI)).sqrt().floor() as usize).max(1);
let theta = riemann_siegel_theta(t);
let mut sum = 0.0;
for k in 1..=n {
sum += (theta - t * (k as f64).ln()).cos() / (k as f64).sqrt();
}
2.0 * sum
}
pub fn zeta_zero_riemann_siegel(n: u64, iterations: usize) -> f64 {
if n == 0 {
return 0.0;
}
let mut t = zeta_zero_approx(n);
let dt = 0.5;
for _ in 0..iterations {
let z_left = riemann_siegel_z(t - dt, 3);
let z_mid = riemann_siegel_z(t, 3);
let z_right = riemann_siegel_z(t + dt, 3);
if z_left.signum() != z_mid.signum() {
t -= dt / 2.0;
} else if z_mid.signum() != z_right.signum() {
t += dt / 2.0;
}
}
t
}
pub fn dedekind_eta(tau_real: f64, tau_imag: f64, terms: usize) -> (f64, f64) {
if tau_imag <= 0.0 {
return (0.0, 0.0);
}
let q = (-2.0 * std::f64::consts::PI * tau_imag).exp()
* (2.0 * std::f64::consts::PI * tau_real).cos();
let _q_imag = (-2.0 * std::f64::consts::PI * tau_imag).exp()
* (2.0 * std::f64::consts::PI * tau_real).sin();
let q24_real = (std::f64::consts::PI * tau_imag / 12.0).exp()
* (std::f64::consts::PI * tau_real / 12.0).cos();
let q24_imag = (std::f64::consts::PI * tau_imag / 12.0).exp()
* (std::f64::consts::PI * tau_real / 12.0).sin();
let mut prod_real = 1.0;
let mut prod_imag = 0.0;
for n in 1..=terms {
let qn = q.powi(n as i32);
let qn_imag = 0.0;
let factor_real = 1.0 - qn;
let factor_imag = -qn_imag;
let new_real = prod_real * factor_real - prod_imag * factor_imag;
let new_imag = prod_real * factor_imag + prod_imag * factor_real;
prod_real = new_real;
prod_imag = new_imag;
}
let eta_real = q24_real * prod_real - q24_imag * prod_imag;
let eta_imag = q24_real * prod_imag + q24_imag * prod_real;
(eta_real, eta_imag)
}
pub fn j_invariant_q_expansion(q: f64, terms: usize) -> f64 {
if q <= 0.0 || q >= 1.0 {
return f64::NAN;
}
let mut sum = q.powi(-1) + 744.0;
let coeffs = [
196884.0,
21493760.0,
864299970.0,
20245856256.0,
333202640600.0,
];
for (i, &c) in coeffs.iter().take(terms).enumerate() {
sum += c * q.powi((i + 1) as i32);
}
sum
}
pub fn divides_monster_order(n: u64) -> bool {
n != 0 && {
let monster_factors: [(u64, u32); 15] = [
(2, 46),
(3, 20),
(5, 9),
(7, 6),
(11, 2),
(13, 3),
(17, 1),
(19, 1),
(23, 1),
(29, 1),
(31, 1),
(41, 1),
(47, 1),
(59, 1),
(71, 1),
];
let mut remaining = n;
for (p, max_exp) in &monster_factors {
let mut exp = 0;
while remaining.is_multiple_of(*p) && exp < *max_exp {
remaining /= p;
exp += 1;
}
}
remaining == 1
}
}
pub fn monster_order_string() -> &'static str {
"808017424794512875886459904961710757005754368000000000"
}
pub fn has_13_cube_structure(n: u64) -> bool {
if n.is_multiple_of(13) {
let q = n / 13;
q.is_multiple_of(13) && (q / 13).is_multiple_of(13)
} else {
false
}
}
pub fn analyze_13_symmetries(n: u64) -> (u32, u32, u32) {
if n == 0 {
return (0, 0, 0);
}
let mut visible_count = 0u32;
let mut remaining = n;
while remaining.is_multiple_of(13) {
remaining /= 13;
visible_count += 1;
}
let monster_required = 3u32;
let hidden_count = monster_required.saturating_sub(visible_count);
(visible_count, hidden_count, visible_count)
}
pub fn find_monster_compatible_13_symmetry(k: u32, max_search: u64) -> Vec<u64> {
let mut results = Vec::new();
let base = 13u64.pow(k);
let monster_primes: [(u64, u32); 14] = [
(2, 46),
(3, 20),
(5, 9),
(7, 6),
(11, 2),
(17, 1),
(19, 1),
(23, 1),
(29, 1),
(31, 1),
(41, 1),
(47, 1),
(59, 1),
(71, 1),
];
for m in 1..=max_search / base {
let n = base * m;
if n > max_search {
break;
}
let mut monster_prime_count = 0;
for (p, _max_exp) in &monster_primes {
if m % p == 0 {
monster_prime_count += 1;
}
}
if monster_prime_count >= 3 {
results.push(n);
}
}
results
}
pub fn valuation_13(n: u64) -> u32 {
if n == 0 {
return 0;
}
let mut count = 0;
let mut remaining = n;
while remaining.is_multiple_of(13) {
remaining /= 13;
count += 1;
}
count
}
pub fn has_metatron_13_structure(n: u64) -> bool {
if n.is_multiple_of(13) {
let level1 = n / 13;
let has_level2 =
level1.is_multiple_of(12) || level1.is_multiple_of(6) || level1.is_multiple_of(4);
let remaining = if has_level2 {
if level1.is_multiple_of(12) {
level1 / 12
} else if level1.is_multiple_of(6) {
level1 / 6
} else {
level1 / 4
}
} else {
level1
};
has_level2 && remaining <= 100
} else {
false
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_is_prime() {
assert!(!is_prime(0));
assert!(!is_prime(1));
assert!(is_prime(2));
assert!(is_prime(3));
assert!(!is_prime(4));
assert!(is_prime(409));
assert!(!is_prime(1679)); }
#[test]
fn test_1679_is_not_prime() {
assert!(!is_prime(1679)); }
#[test]
fn test_sieve() {
let primes = sieve_primes(30);
assert_eq!(primes, vec![2, 3, 5, 7, 11, 13, 17, 19, 23, 29]);
}
#[test]
fn test_factor_trial() {
let factors = factor_trial(1679);
assert_eq!(factors.get(&23), Some(&1));
assert_eq!(factors.get(&73), Some(&1));
}
#[test]
fn test_semiprime_factors() {
let result = semiprime_factors(1679);
assert!(result.is_some());
let (p, q) = result.unwrap();
assert_eq!(p * q, 1679);
assert_eq!(semiprime_factors(100), None); }
#[test]
fn test_factor_semiprime_pi_family() {
let result = factor_semiprime_pi_family(1679, 10);
assert!(result.is_some());
let (p, q) = result.unwrap();
assert_eq!(p * q, 1679);
assert!(factor_semiprime_pi_family(154, 10).is_some()); assert!(factor_semiprime_pi_family(385, 10).is_some()); }
#[test]
fn test_zeta() {
let z2 = zeta_real(2.0, 100000);
assert!((z2 - std::f64::consts::PI * std::f64::consts::PI / 6.0).abs() < 0.01);
}
#[test]
fn test_continued_fraction() {
let conv = continued_fraction(std::f64::consts::PI, 10);
let (p, q) = conv[3]; assert_eq!(p, 355);
assert_eq!(q, 113);
}
#[test]
fn test_mod_pow() {
assert_eq!(mod_pow(2, 10, 1000), 24);
assert_eq!(mod_pow(3, 5, 7), 5);
}
#[test]
fn test_pollard_rho() {
let factor = pollard_rho(1679, 1);
assert!(factor.is_some());
let f = factor.unwrap();
assert_eq!(1679 % f, 0);
assert!(f > 1 && f < 1679);
let n = 10403; let factor = pollard_rho(n, 1);
assert!(factor.is_some());
let f = factor.unwrap();
assert_eq!(n % f, 0);
}
#[test]
fn test_factor_advanced() {
let factors = factor_advanced(1679);
assert_eq!(factors.get(&23), Some(&1));
assert_eq!(factors.get(&73), Some(&1));
let factors = factor_advanced(10403);
assert_eq!(factors.get(&101), Some(&1));
assert_eq!(factors.get(&103), Some(&1));
}
#[test]
fn test_gcd() {
assert_eq!(gcd(48, 18), 6);
assert_eq!(gcd(17, 13), 1);
assert_eq!(gcd(100, 25), 25);
}
#[test]
fn test_miller_rabin() {
assert!(is_prime_miller_rabin(2));
assert!(is_prime_miller_rabin(3));
assert!(is_prime_miller_rabin(409));
assert!(is_prime_miller_rabin(2803));
assert!(!is_prime_miller_rabin(0));
assert!(!is_prime_miller_rabin(1));
assert!(!is_prime_miller_rabin(4));
assert!(!is_prime_miller_rabin(1679)); assert!(!is_prime_miller_rabin(100));
assert!(!is_prime_miller_rabin(561)); assert!(!is_prime_miller_rabin(1105)); assert!(!is_prime_miller_rabin(1729));
assert!(is_prime_miller_rabin(104729)); }
#[test]
fn test_mod_inverse() {
assert_eq!(mod_inverse(3, 11), Some(4)); assert_eq!(mod_inverse(2, 4), None);
}
#[test]
fn test_riemann_siegel() {
let theta = riemann_siegel_theta(14.13);
assert!(theta.is_finite());
let z = riemann_siegel_z(14.13, 3);
assert!(z.is_finite());
}
#[test]
fn test_monster_moonshine() {
assert!(divides_monster_order(2197));
assert!(has_13_cube_structure(2197));
assert!(!has_13_cube_structure(169));
assert_eq!(
monster_order_string(),
"808017424794512875886459904961710757005754368000000000"
);
let j = j_invariant_q_expansion(0.001, 1);
assert!(j > 1000.0);
let (eta_r, eta_i) = dedekind_eta(0.0, 1.0, 10);
assert!(eta_r.is_finite());
assert!(eta_i.is_finite());
let (visible, hidden, total) = analyze_13_symmetries(2197);
assert_eq!(visible, 3);
assert_eq!(hidden, 0);
assert_eq!(total, 3);
let (visible, hidden, total) = analyze_13_symmetries(13);
assert_eq!(visible, 1);
assert_eq!(hidden, 2); assert_eq!(total, 1);
assert_eq!(valuation_13(2197), 3);
assert_eq!(valuation_13(13), 1);
assert_eq!(valuation_13(1), 0);
assert!(has_metatron_13_structure(156)); assert!(!has_metatron_13_structure(13));
let compatible = find_monster_compatible_13_symmetry(1, 10000);
assert!(!compatible.is_empty());
for &n in &compatible {
assert_eq!(n % 13, 0);
}
}
}