diff --git a/DIRECTORY.md b/DIRECTORY.md index 3685ba5bf56..5282d2b4a0e 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -194,6 +194,7 @@ * [Doomsday](https://github.com/TheAlgorithms/Rust/blob/master/src/math/doomsday.rs) * [Elliptic Curve](https://github.com/TheAlgorithms/Rust/blob/master/src/math/elliptic_curve.rs) * [Euclidean Distance](https://github.com/TheAlgorithms/Rust/blob/master/src/math/euclidean_distance.rs) + * [Euler Totient](https://github.com/TheAlgorithms/Rust/blob/master/src/math/euler_totient.rs) * [Exponential Linear Unit](https://github.com/TheAlgorithms/Rust/blob/master/src/math/exponential_linear_unit.rs) * [Extended Euclidean Algorithm](https://github.com/TheAlgorithms/Rust/blob/master/src/math/extended_euclidean_algorithm.rs) * [Factorial](https://github.com/TheAlgorithms/Rust/blob/master/src/math/factorial.rs) diff --git a/src/math/euler_totient.rs b/src/math/euler_totient.rs new file mode 100644 index 00000000000..9605e33e0af --- /dev/null +++ b/src/math/euler_totient.rs @@ -0,0 +1,45 @@ +/// ## Euler's Totient (`φ(n)`) +/// +/// Calculate the **Euler's Totient** function of a given number `n`. +/// +/// Wikipedia: https://en.wikipedia.org/wiki/Euler%27s_totient_function +pub fn euler_totient(mut n: i64) -> i64 { + let mut result = n; + + if n <= 0 { + panic!("Must be a positive integer!"); + } + + for i in 2..=n.isqrt() { + if n % i == 0 { + while n % i == 0 { + n /= i; + } + result -= result / i; + } + } + + if n > 1 { + result -= result / n; + } + + result +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_euler_totient() { + assert_eq!(euler_totient(1), 1); + assert_eq!(euler_totient(325), 240); + assert_eq!(euler_totient(746), 372); + assert_eq!(euler_totient(3_639), 2_424); + assert_eq!(euler_totient(98_354), 49_176); + assert_eq!(euler_totient(123_456), 41_088); + assert_eq!(euler_totient(493_123_235), 347_518_080); + assert_eq!(euler_totient(945_243_784_032), 315_074_904_192); + assert_eq!(euler_totient(372_036_854_775_808), 185_661_377_740_800); + } +} diff --git a/src/math/mod.rs b/src/math/mod.rs index 7407465c3b0..7b404f0f8e0 100644 --- a/src/math/mod.rs +++ b/src/math/mod.rs @@ -19,6 +19,7 @@ mod decimal_to_fraction; mod doomsday; mod elliptic_curve; mod euclidean_distance; +mod euler_totient; mod exponential_linear_unit; mod extended_euclidean_algorithm; pub mod factorial; @@ -103,6 +104,7 @@ pub use self::decimal_to_fraction::decimal_to_fraction; pub use self::doomsday::get_week_day; pub use self::elliptic_curve::EllipticCurve; pub use self::euclidean_distance::euclidean_distance; +pub use self::euler_totient::euler_totient; pub use self::exponential_linear_unit::exponential_linear_unit; pub use self::extended_euclidean_algorithm::extended_euclidean_algorithm; pub use self::factorial::{factorial, factorial_bigmath, factorial_recursive};