#![allow(clippy::cast_sign_loss)] #![allow(clippy::cast_possible_truncation)]
use gcd::Gcd;
use prime_factorization::Factorization;
use integer_sqrt::IntegerSquareRoot;
pub const TEST_POWERFUL:[i32; 30] = [1, 4, 8, 9, 16, 25, 27, 32, 36, 49,
64, 72, 81, 100, 108, 121, 125, 128, 144, 169,
196, 200, 216, 225, 243, 256, 288, 289, 324, 343];
pub const TEST_ACHILLES:[i32; 30] = [72, 108, 200, 288, 392, 500, 648, 675, 800, 968,
972, 1125, 1323, 1352, 1568, 1800, 1944, 2000, 2700, 2888,
3087, 3200, 3267, 3528, 4000, 4232, 4500, 4563, 4608, 5000];
pub const TEST_PERFECT:[i32; 30] = [4, 8, 9, 16, 25, 27, 32, 36, 49, 64,
81, 100, 121, 125, 128, 144, 169, 196, 216, 225,
243, 256, 289, 324, 343, 361, 400, 441, 484, 512];
pub const TEST_SEMIPRIME:[i32; 30] = [4, 6, 9, 10, 14, 15, 21, 22, 25, 26,
33, 34, 35, 38, 39, 46, 49, 51, 55, 57,
58, 62, 65, 69, 74, 77, 82, 85, 86, 87];
pub const TEST_SPHENIC: [i32; 30] = [30, 42, 66, 70, 78, 102, 105, 110, 114, 130,
138, 154, 165, 170, 174, 182, 186, 190, 195, 222,
230, 231, 238, 246, 255, 258, 266, 273, 282, 285];
pub const TEST_SQUAREFREE: [i32; 30] = [1, 2, 3, 5, 6, 7, 10, 11, 13, 14,
15, 17, 19, 21, 22, 23, 26, 29, 30, 31,
33, 34, 35, 37, 38, 39, 41, 42, 43, 46];
pub const TEST_PRONIC: [i32; 30] = [2, 6, 12, 20, 30, 42, 56, 72, 90,
110, 132, 156, 182, 210, 240, 272, 306, 342, 380,
420, 462, 506, 552, 600, 650, 702, 756, 812, 870, 930];
pub fn is_powerful(testee: i32) -> bool {
if testee < 0 {return false;}
let unsigned_testee:u64 = u64::from(testee.unsigned_abs());
let factor_factory: Factorization<u64> = Factorization::run(unsigned_testee);
let prime_factors:Vec<(u64, u32)> = factor_factory.prime_factor_repr();
let mut b;
let mut odd_factors = vec![];
for prime in prime_factors{
if prime.1 % 2 == 1 {odd_factors.push(prime.0);}
}
if odd_factors.is_empty() {
b = 1;
}
else {
b = odd_factors[0];
odd_factors.remove(0);
for odd in odd_factors {
b *= odd;
}
};
let radicand_of_a: u64 = unsigned_testee / b.pow(3);
let test: u64 = radicand_of_a * b.pow(3); if unsigned_testee == test {return true;}
false
}
#[test]
fn test_is_powerful(){
for &i in &TEST_POWERFUL {
assert!(is_powerful(i));
}
assert!(!is_powerful(19));
assert!(!is_powerful(-20));
assert!(!is_powerful(-25));
}
pub fn is_achilles(testee: i32) -> bool {
if is_perfect_power(testee) {return false;}
if is_powerful(testee){
if is_perfect_power(testee) {return false;}
let unsigned_testee:u64 = u64::from(testee.unsigned_abs());
let factor_factory: Factorization<u64> = Factorization::run(unsigned_testee);
let prime_factors:Vec<(u64, u32)> = factor_factory.prime_factor_repr();
for factor in prime_factors{
let factor_squared = factor.0.pow(2);
if unsigned_testee % factor_squared != 0 {return false;} }
return true;
};
false
}
#[test]
fn test_is_achilles(){
for &i in &TEST_ACHILLES {
assert!(is_achilles(i));
}
assert!(!is_achilles(360));
assert!(!is_achilles(784));
assert!(!is_achilles(-72));
}
pub fn is_perfect_power(testee: i32) -> bool {
if !is_powerful(testee) {return false;};
let unsigned_testee: u64 = u64::from(testee.unsigned_abs());
let factor_factory: Factorization<u64> = Factorization::run(unsigned_testee);
let prime_factors:Vec<(u64, u32)> = factor_factory.prime_factor_repr();
let mut gcd_of_prime_powers = prime_factors[0].1;
for prime_power in &prime_factors[1..] {
gcd_of_prime_powers = gcd_of_prime_powers.gcd(prime_power.1);
}
if gcd_of_prime_powers > 1 {
return true;
}
false
}
#[test]
fn test_is_perfect_power(){
for &i in &TEST_PERFECT {
assert!(is_perfect_power(i));
}
assert!(!is_perfect_power(360));
assert!(!is_perfect_power(785));
assert!(!is_perfect_power(-72));
}
pub fn is_semiprime(testee: i32) -> bool{
if testee < 4 {return false;}
let unsigned_testee:u64 = u64::from(testee.unsigned_abs());
let factor_factory: Factorization<u64> = Factorization::run(unsigned_testee);
let prime_factors:Vec<(u64, u32)> = factor_factory.prime_factor_repr();
if prime_factors.len() == 2{
return true;
}
if prime_factors.len() == 1 && prime_factors[0].1 == 2 {
return true;
}
false
}
#[test]
fn test_is_semiprime(){
for &i in &TEST_SEMIPRIME {
assert!(is_semiprime(i));
assert!(!is_semiprime(19));
assert!(!is_semiprime(786));
assert!(!is_semiprime(-72));
}
}
pub fn is_sphenic(testee: i32) -> bool {
if testee < 4 {return false;}
let unsigned_testee:u64 = u64::from(testee.unsigned_abs());
let factor_factory: Factorization<u64> = Factorization::run(unsigned_testee);
let prime_factors:Vec<(u64, u32)> = factor_factory.prime_factor_repr();
if prime_factors.len() == 3{
return true;
}
false
}
#[test]
fn test_is_sphenic(){
for &borrow_i in &(TEST_SPHENIC) {
let i: i32 = borrow_i;
assert!(is_sphenic(i));
assert!(!is_sphenic(19));
assert!(is_sphenic(786));
assert!(!is_sphenic(788));
assert!(!is_sphenic(72));
}}
pub fn is_squarefree(testee: i32) -> bool {
let unsigned_testee:u64 = u64::from(testee.unsigned_abs());
let factor_factory: Factorization<u64> = Factorization::run(unsigned_testee);
let prime_factors:Vec<(u64, u32)> = factor_factory.prime_factor_repr();
for prime in prime_factors{
if prime.1 > 1 {return false;}
}
true
}
#[test]
fn test_is_squarefree(){
for i in &TEST_SQUAREFREE {
assert!(is_squarefree(*i));
assert!(!is_squarefree(8));
assert!(!is_squarefree(9));
}
}
pub fn is_pronic(testee: i32) -> bool {
let mut sqrt: i32 = 2;
if testee < 0 {return false;}
if testee == 0 {return true;}
if testee > 0 {sqrt = testee.integer_sqrt();}
for i in 0..=sqrt {
if i * (i + 1) == testee {
return true;
}
}
false
}
#[test]
fn test_is_pronic(){
for i in &TEST_PRONIC {
assert!(is_pronic(*i));}
assert!(!is_pronic(8));
assert!(!is_pronic(10));
}
pub fn is_smooth(testee: i32, smoothing: u32) -> bool {
let unsigned_testee:u64 = u64::from(testee.unsigned_abs());
let factor_factory: Factorization<u64> = Factorization::run(unsigned_testee);
let prime_factors:Vec<(u64, u32)> = factor_factory.prime_factor_repr();
let max_factor: u64 = prime_factors.last().unwrap().0;
if u64::from(smoothing) <= max_factor{
return true;
}
false
}
pub fn is_rough(testee: i32, rough: u32) -> bool {
let unsigned_testee:u64 = u64::from(testee.unsigned_abs());
let factor_factory: Factorization<u64> = Factorization::run(unsigned_testee);
let prime_factors:Vec<(u64, u32)> = factor_factory.prime_factor_repr();
let least_factor: u64 = prime_factors.first().unwrap().0;
if least_factor > u64::from(rough){
return true;
}
false
}
pub fn is_unusual(testee: i32) -> bool {
let unsigned_testee:u64 = u64::from(testee.unsigned_abs());
let factor_factory: Factorization<u64> = Factorization::run(unsigned_testee);
let prime_factors:Vec<(u64, u32)> = factor_factory.prime_factor_repr();
let max_factor: u64 = prime_factors.last().unwrap().0;
let sqrt = f64::from(testee).sqrt();
if max_factor >= sqrt.floor() as u64 {
return true;
}
if max_factor == sqrt.floor() as u64 && sqrt.fract() > 0.0{
return true;
}
false
}