#[cfg(test)]
mod tests {
use crate::engine::number_theory::NumberTheoryEngine;
use crate::core::{Expression, Number};
use num_bigint::BigInt;
use num_rational::BigRational;
fn create_engine() -> NumberTheoryEngine {
NumberTheoryEngine::new()
}
#[test]
fn test_gcd_integers() {
let engine = create_engine();
let a = Expression::Number(Number::Integer(BigInt::from(48)));
let b = Expression::Number(Number::Integer(BigInt::from(18)));
let result = engine.gcd(&a, &b).unwrap();
assert_eq!(result, Expression::Number(Number::Integer(BigInt::from(6))));
let a = Expression::Number(Number::Integer(BigInt::from(17)));
let b = Expression::Number(Number::Integer(BigInt::from(13)));
let result = engine.gcd(&a, &b).unwrap();
assert_eq!(result, Expression::Number(Number::Integer(BigInt::from(1))));
let a = Expression::Number(Number::Integer(BigInt::from(0)));
let b = Expression::Number(Number::Integer(BigInt::from(5)));
let result = engine.gcd(&a, &b).unwrap();
assert_eq!(result, Expression::Number(Number::Integer(BigInt::from(5))));
}
#[test]
fn test_gcd_rationals() {
let engine = create_engine();
let a = Expression::Number(Number::Rational(BigRational::new(BigInt::from(6), BigInt::from(4))));
let b = Expression::Number(Number::Rational(BigRational::new(BigInt::from(9), BigInt::from(6))));
let result = engine.gcd(&a, &b).unwrap();
let expected = Expression::Number(Number::Rational(BigRational::new(BigInt::from(3), BigInt::from(2))));
assert_eq!(result, expected);
}
#[test]
fn test_lcm_integers() {
let engine = create_engine();
let a = Expression::Number(Number::Integer(BigInt::from(12)));
let b = Expression::Number(Number::Integer(BigInt::from(8)));
let result = engine.lcm(&a, &b).unwrap();
assert_eq!(result, Expression::Number(Number::Integer(BigInt::from(24))));
let a = Expression::Number(Number::Integer(BigInt::from(7)));
let b = Expression::Number(Number::Integer(BigInt::from(11)));
let result = engine.lcm(&a, &b).unwrap();
assert_eq!(result, Expression::Number(Number::Integer(BigInt::from(77))));
let a = Expression::Number(Number::Integer(BigInt::from(0)));
let b = Expression::Number(Number::Integer(BigInt::from(5)));
let result = engine.lcm(&a, &b).unwrap();
assert_eq!(result, Expression::Number(Number::Integer(BigInt::from(0))));
}
#[test]
fn test_is_prime() {
let engine = create_engine();
let primes = vec![2, 3, 5, 7, 11, 13, 17, 19, 23, 29];
for p in primes {
let n = Expression::Number(Number::Integer(BigInt::from(p)));
assert!(engine.is_prime(&n).unwrap(), "{} 应该是素数", p);
}
let composites = vec![4, 6, 8, 9, 10, 12, 14, 15, 16, 18];
for c in composites {
let n = Expression::Number(Number::Integer(BigInt::from(c)));
assert!(!engine.is_prime(&n).unwrap(), "{} 不应该是素数", c);
}
let n = Expression::Number(Number::Integer(BigInt::from(1)));
assert!(!engine.is_prime(&n).unwrap(), "1 不是素数");
let n = Expression::Number(Number::Integer(BigInt::from(0)));
assert!(!engine.is_prime(&n).unwrap(), "0 不是素数");
}
#[test]
fn test_prime_factors() {
let engine = create_engine();
let n = Expression::Number(Number::Integer(BigInt::from(12)));
let factors = engine.prime_factors(&n).unwrap();
let expected = vec![
Expression::Number(Number::Integer(BigInt::from(2))),
Expression::Number(Number::Integer(BigInt::from(2))),
Expression::Number(Number::Integer(BigInt::from(3))),
];
assert_eq!(factors, expected);
let n = Expression::Number(Number::Integer(BigInt::from(17)));
let factors = engine.prime_factors(&n).unwrap();
let expected = vec![Expression::Number(Number::Integer(BigInt::from(17)))];
assert_eq!(factors, expected);
let n = Expression::Number(Number::Integer(BigInt::from(60)));
let factors = engine.prime_factors(&n).unwrap();
let expected = vec![
Expression::Number(Number::Integer(BigInt::from(2))),
Expression::Number(Number::Integer(BigInt::from(2))),
Expression::Number(Number::Integer(BigInt::from(3))),
Expression::Number(Number::Integer(BigInt::from(5))),
];
assert_eq!(factors, expected);
}
#[test]
fn test_binomial_coefficient() {
let engine = create_engine();
let n = Expression::Number(Number::Integer(BigInt::from(5)));
let k = Expression::Number(Number::Integer(BigInt::from(2)));
let result = engine.binomial(&n, &k).unwrap();
assert_eq!(result, Expression::Number(Number::Integer(BigInt::from(10))));
let n = Expression::Number(Number::Integer(BigInt::from(10)));
let k = Expression::Number(Number::Integer(BigInt::from(0)));
let result = engine.binomial(&n, &k).unwrap();
assert_eq!(result, Expression::Number(Number::Integer(BigInt::from(1))));
let n = Expression::Number(Number::Integer(BigInt::from(7)));
let k = Expression::Number(Number::Integer(BigInt::from(7)));
let result = engine.binomial(&n, &k).unwrap();
assert_eq!(result, Expression::Number(Number::Integer(BigInt::from(1))));
let n = Expression::Number(Number::Integer(BigInt::from(8)));
let k1 = Expression::Number(Number::Integer(BigInt::from(3)));
let k2 = Expression::Number(Number::Integer(BigInt::from(5)));
let result1 = engine.binomial(&n, &k1).unwrap();
let result2 = engine.binomial(&n, &k2).unwrap();
assert_eq!(result1, result2);
}
#[test]
fn test_permutation() {
let engine = create_engine();
let n = Expression::Number(Number::Integer(BigInt::from(5)));
let k = Expression::Number(Number::Integer(BigInt::from(3)));
let result = engine.permutation(&n, &k).unwrap();
assert_eq!(result, Expression::Number(Number::Integer(BigInt::from(60))));
let n = Expression::Number(Number::Integer(BigInt::from(10)));
let k = Expression::Number(Number::Integer(BigInt::from(0)));
let result = engine.permutation(&n, &k).unwrap();
assert_eq!(result, Expression::Number(Number::Integer(BigInt::from(1))));
let n = Expression::Number(Number::Integer(BigInt::from(4)));
let k = Expression::Number(Number::Integer(BigInt::from(4)));
let result = engine.permutation(&n, &k).unwrap();
assert_eq!(result, Expression::Number(Number::Integer(BigInt::from(24)))); }
#[test]
fn test_mean() {
let engine = create_engine();
let values = vec![
Expression::Number(Number::Integer(BigInt::from(1))),
Expression::Number(Number::Integer(BigInt::from(2))),
Expression::Number(Number::Integer(BigInt::from(3))),
Expression::Number(Number::Integer(BigInt::from(4))),
Expression::Number(Number::Integer(BigInt::from(5))),
];
let result = engine.mean(&values).unwrap();
assert_eq!(result, Expression::Number(Number::Rational(BigRational::new(BigInt::from(15), BigInt::from(5)))));
let values = vec![
Expression::Number(Number::Rational(BigRational::new(BigInt::from(1), BigInt::from(2)))),
Expression::Number(Number::Rational(BigRational::new(BigInt::from(3), BigInt::from(4)))),
];
let result = engine.mean(&values).unwrap();
let expected = Expression::Number(Number::Rational(BigRational::new(BigInt::from(5), BigInt::from(8))));
assert_eq!(result, expected);
}
#[test]
fn test_variance() {
let engine = create_engine();
let values = vec![
Expression::Number(Number::Integer(BigInt::from(1))),
Expression::Number(Number::Integer(BigInt::from(2))),
Expression::Number(Number::Integer(BigInt::from(3))),
];
let result = engine.variance(&values).unwrap();
let expected = Expression::Number(Number::Rational(BigRational::new(BigInt::from(2), BigInt::from(3))));
assert_eq!(result, expected);
}
#[test]
fn test_standard_deviation() {
let engine = create_engine();
let values = vec![
Expression::Number(Number::Integer(BigInt::from(0))),
Expression::Number(Number::Integer(BigInt::from(4))),
];
let result = engine.standard_deviation(&values).unwrap();
match result {
Expression::Number(Number::Integer(n)) => {
assert_eq!(n, BigInt::from(2));
}
Expression::Number(Number::Rational(r)) => {
assert_eq!(r, BigRational::new(BigInt::from(2), BigInt::from(1)));
}
_ => panic!("期望得到数值结果"),
}
}
#[test]
fn test_error_cases() {
let engine = create_engine();
let a = Expression::Variable("x".to_string());
let b = Expression::Number(Number::Integer(BigInt::from(5)));
assert!(engine.gcd(&a, &b).is_err());
assert!(engine.lcm(&a, &b).is_err());
assert!(engine.is_prime(&a).is_err());
assert!(engine.prime_factors(&a).is_err());
assert!(engine.binomial(&a, &b).is_err());
assert!(engine.permutation(&a, &b).is_err());
let empty_values: Vec<Expression> = vec![];
assert!(engine.mean(&empty_values).is_err());
let single_value = vec![Expression::Number(Number::Integer(BigInt::from(5)))];
assert!(engine.variance(&single_value).is_err());
let zero = Expression::Number(Number::Integer(BigInt::from(0)));
assert!(engine.prime_factors(&zero).is_err());
let one = Expression::Number(Number::Integer(BigInt::from(1)));
assert!(engine.prime_factors(&one).is_err());
}
#[test]
fn test_large_numbers() {
let engine = create_engine();
let a = Expression::Number(Number::Integer(BigInt::from(123456789)));
let b = Expression::Number(Number::Integer(BigInt::from(987654321)));
let result = engine.gcd(&a, &b).unwrap();
assert_eq!(result, Expression::Number(Number::Integer(BigInt::from(9))));
let n = Expression::Number(Number::Integer(BigInt::from(20)));
let k = Expression::Number(Number::Integer(BigInt::from(10)));
let result = engine.binomial(&n, &k).unwrap();
assert_eq!(result, Expression::Number(Number::Integer(BigInt::from(184756))));
}
#[test]
fn test_negative_numbers() {
let engine = create_engine();
let a = Expression::Number(Number::Integer(BigInt::from(-12)));
let b = Expression::Number(Number::Integer(BigInt::from(8)));
let result = engine.gcd(&a, &b).unwrap();
assert_eq!(result, Expression::Number(Number::Integer(BigInt::from(4))));
let result = engine.lcm(&a, &b).unwrap();
assert_eq!(result, Expression::Number(Number::Integer(BigInt::from(24))));
}
#[test]
fn test_rational_arithmetic() {
let engine = create_engine();
let values = vec![
Expression::Number(Number::Rational(BigRational::new(BigInt::from(1), BigInt::from(3)))),
Expression::Number(Number::Rational(BigRational::new(BigInt::from(1), BigInt::from(6)))),
Expression::Number(Number::Rational(BigRational::new(BigInt::from(1), BigInt::from(2)))),
];
let result = engine.mean(&values).unwrap();
let expected = Expression::Number(Number::Rational(BigRational::new(BigInt::from(1), BigInt::from(3))));
assert_eq!(result, expected);
}
}