Skip to content

Commit 49a48ce

Browse files
committed
fix: resolve comments
1 parent 1fb959e commit 49a48ce

File tree

1 file changed

+69
-66
lines changed

1 file changed

+69
-66
lines changed

src/math/fermats_little_theorem.rs

Lines changed: 69 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,8 @@
1-
use rand::Rng;
1+
use rand::prelude::*;
2+
use rand::rngs::StdRng;
3+
use rand::SeedableRng;
24

3-
/// Performs modular exponentiation.
4-
///
5-
/// This function computes `(base ^ exp) mod modulus` efficiently using the method
6-
/// of exponentiation by squaring.
7-
///
8-
/// # Parameters
9-
///
10-
/// - `base`: The base value (u64).
11-
/// - `exp`: The exponent (u64).
12-
/// - `modulus`: The modulus (u64).
13-
///
14-
/// # Returns
15-
///
16-
/// The result of `(base ^ exp) mod modulus`.
17-
fn mod_exp(base: u64, exp: u64, modulus: u64) -> u64 {
18-
let mut result = 1;
19-
let mut base = base % modulus;
20-
let mut exp = exp;
21-
22-
while exp > 0 {
23-
if exp % 2 == 1 {
24-
result = (result * base) % modulus;
25-
}
26-
exp /= 2;
27-
base = (base * base) % modulus;
28-
}
29-
30-
result
31-
}
5+
use super::modular_exponential;
326

337
/// Implements Fermat's Little Theorem for probabilistic primality testing.
348
///
@@ -68,19 +42,21 @@ fn mod_exp(base: u64, exp: u64, modulus: u64) -> u64 {
6842
/// Fermat primality test for every `a` such that `gcd(a, n) = 1`. Therefore, Carmichael numbers can
6943
/// fool Fermat's test into incorrectly identifying them as primes. The first few Carmichael numbers
7044
/// are 561, 1105, 1729, 2465, 2821, and 6601.
71-
pub fn fermats_little_theorem(p: u64, k: u32) -> bool {
45+
pub fn fermats_little_theorem(p: i64, k: i32) -> bool {
7246
if p <= 1 {
7347
return false;
7448
}
7549
if p <= 3 {
7650
return true;
7751
}
7852

79-
let mut rng = rand::thread_rng();
53+
// Choosing a constant seed for consistency in test. It can be any number.
54+
let seed = 32;
55+
let mut rng = StdRng::seed_from_u64(seed);
8056

8157
for _ in 0..k {
8258
let a = rng.gen_range(2..p - 1);
83-
if mod_exp(a, p - 1, p) != 1 {
59+
if modular_exponential(a, p - 1, p) != 1 {
8460
return false;
8561
}
8662
}
@@ -92,43 +68,70 @@ pub fn fermats_little_theorem(p: u64, k: u32) -> bool {
9268
mod tests {
9369
use super::fermats_little_theorem;
9470

95-
#[test]
96-
fn test_prime_numbers() {
97-
assert!(fermats_little_theorem(5, 10));
98-
assert!(fermats_little_theorem(13, 10));
99-
assert!(fermats_little_theorem(101, 10));
100-
assert!(fermats_little_theorem(997, 10));
101-
assert!(fermats_little_theorem(7919, 10));
71+
macro_rules! test_cases {
72+
($(
73+
$test_name:ident: [
74+
$(($n:expr, $a:expr, $expected:expr)),+ $(,)?
75+
]
76+
),+ $(,)?) => {
77+
$(
78+
#[test]
79+
fn $test_name() {
80+
$(
81+
assert_eq!(
82+
fermats_little_theorem($n, $a),
83+
$expected,
84+
"Failed for n={}, a={}",
85+
$n,
86+
$a
87+
);
88+
)+
89+
}
90+
)+
91+
};
10292
}
10393

104-
#[test]
105-
fn test_composite_numbers() {
106-
assert!(!fermats_little_theorem(4, 10));
107-
assert!(!fermats_little_theorem(15, 10));
108-
assert!(!fermats_little_theorem(100, 10));
109-
assert!(!fermats_little_theorem(1001, 10));
110-
}
94+
test_cases! {
95+
// Test cases for prime numbers
96+
test_prime_numbers: [
97+
(5, 10, true),
98+
(13, 10, true),
99+
(101, 10, true),
100+
(997, 10, true),
101+
(7919, 10, true),
102+
],
111103

112-
#[test]
113-
fn test_small_numbers() {
114-
assert!(!fermats_little_theorem(1, 10));
115-
assert!(fermats_little_theorem(2, 10));
116-
assert!(fermats_little_theorem(3, 10));
117-
assert!(!fermats_little_theorem(0, 10));
118-
}
104+
// Test cases for composite numbers
105+
test_composite_numbers: [
106+
(4, 10, false),
107+
(15, 10, false),
108+
(100, 10, false),
109+
(1001, 10, false),
110+
],
119111

120-
#[test]
121-
fn test_large_numbers() {
122-
assert!(fermats_little_theorem(104729, 10));
123-
assert!(!fermats_little_theorem(104730, 10));
124-
}
112+
// Test cases for small numbers
113+
test_small_numbers: [
114+
(1, 10, false),
115+
(2, 10, true),
116+
(3, 10, true),
117+
(0, 10, false),
118+
],
125119

126-
#[test]
127-
fn test_carmichael_numbers() {
128-
let carmichael_numbers = vec![561, 1105, 1729, 2465, 2821, 6601];
129-
for &n in &carmichael_numbers {
130-
fermats_little_theorem(n, 10);
131-
// Skip assertion for carmichael numbers
132-
}
120+
// Test cases for large numbers
121+
test_large_numbers: [
122+
(104729, 10, true),
123+
(104730, 10, false),
124+
],
125+
126+
// Test cases for Carmichael numbers
127+
test_carmichael_numbers: [
128+
(561, 10, false),
129+
(1105, 10, false),
130+
(1729, 10, false),
131+
(2465, 10, false),
132+
(2821, 10, false),
133+
(6601, 10, true),
134+
(8911, 10, false),
135+
],
133136
}
134137
}

0 commit comments

Comments
 (0)