Skip to content

Commit 551269c

Browse files
imp2002siriak
andauthored
feat: add greatest common divisor (TheAlgorithms#254)
Co-authored-by: Andrii Siriak <siryaka@gmail.com>
1 parent c9f3661 commit 551269c

File tree

4 files changed

+90
-0
lines changed

4 files changed

+90
-0
lines changed

DIRECTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
* [Lib](https://github.com/TheAlgorithms/Rust/blob/master/src/lib.rs)
5151
* Math
5252
* [Extended Euclidean Algorithm](https://github.com/TheAlgorithms/Rust/blob/master/src/math/extended_euclidean_algorithm.rs)
53+
* [Greatest Common Divisor](https://github.com/TheAlgorithms/Rust/blob/master/src/math/greatest_common_divisor.rs)
5354
* [Pascal Triangle](https://github.com/TheAlgorithms/Rust/blob/master/src/math/pascal_triangle.rs)
5455
* [Perfect Numbers](https://github.com/TheAlgorithms/Rust/blob/master/src/math/perfect_numbers.rs)
5556
* [Prime Check](https://github.com/TheAlgorithms/Rust/blob/master/src/math/prime_check.rs)

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ RESTART BUILD
3434

3535
## Math
3636
- [x] [Extended euclidean algorithm](./src/math/extended_euclidean_algorithm.rs)
37+
- [x] [Greatest common divisor](./src/math/greatest_common_divisor.rs)
3738
- [x] [Pascal's triangle](./src/math/pascal_triangle.rs)
3839

3940
## [Dynamic Programming](./src/dynamic_programming)

src/math/greatest_common_divisor.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/// Greatest Common Divisor.
2+
///
3+
/// greatest_common_divisor(num1, num2) returns the greatest number of num1 and num2.
4+
///
5+
/// Wikipedia reference: https://en.wikipedia.org/wiki/Greatest_common_divisor
6+
/// gcd(a, b) = gcd(a, -b) = gcd(-a, b) = gcd(-a, -b) by definition of divisibility
7+
8+
pub fn greatest_common_divisor_recursive(a: i64, b: i64) -> i64 {
9+
if a == 0 {
10+
b.abs()
11+
} else {
12+
greatest_common_divisor_recursive(b % a, a)
13+
}
14+
}
15+
16+
pub fn greatest_common_divisor_iterative(mut a: i64, mut b: i64) -> i64 {
17+
while a != 0 {
18+
let remainder = b % a;
19+
b = a;
20+
a = remainder;
21+
}
22+
b.abs()
23+
}
24+
25+
#[cfg(test)]
26+
mod tests {
27+
use super::*;
28+
29+
#[test]
30+
fn positive_number_recursive() {
31+
assert_eq!(greatest_common_divisor_recursive(4, 16), 4);
32+
assert_eq!(greatest_common_divisor_recursive(16, 4), 4);
33+
assert_eq!(greatest_common_divisor_recursive(3, 5), 1);
34+
assert_eq!(greatest_common_divisor_recursive(40, 40), 40);
35+
assert_eq!(greatest_common_divisor_recursive(27, 12), 3);
36+
}
37+
38+
#[test]
39+
fn positive_number_iterative() {
40+
assert_eq!(greatest_common_divisor_iterative(4, 16), 4);
41+
assert_eq!(greatest_common_divisor_iterative(16, 4), 4);
42+
assert_eq!(greatest_common_divisor_iterative(3, 5), 1);
43+
assert_eq!(greatest_common_divisor_iterative(40, 40), 40);
44+
assert_eq!(greatest_common_divisor_iterative(27, 12), 3);
45+
}
46+
47+
#[test]
48+
fn negative_number_recursive() {
49+
assert_eq!(greatest_common_divisor_recursive(-32, -8), 8);
50+
assert_eq!(greatest_common_divisor_recursive(-8, -32), 8);
51+
assert_eq!(greatest_common_divisor_recursive(-3, -5), 1);
52+
assert_eq!(greatest_common_divisor_recursive(-40, -40), 40);
53+
assert_eq!(greatest_common_divisor_recursive(-12, -27), 3);
54+
}
55+
56+
#[test]
57+
fn negative_number_iterative() {
58+
assert_eq!(greatest_common_divisor_iterative(-32, -8), 8);
59+
assert_eq!(greatest_common_divisor_iterative(-8, -32), 8);
60+
assert_eq!(greatest_common_divisor_iterative(-3, -5), 1);
61+
assert_eq!(greatest_common_divisor_iterative(-40, -40), 40);
62+
assert_eq!(greatest_common_divisor_iterative(-12, -27), 3);
63+
}
64+
65+
#[test]
66+
fn mix_recursive() {
67+
assert_eq!(greatest_common_divisor_recursive(0, -5), 5);
68+
assert_eq!(greatest_common_divisor_recursive(-5, 0), 5);
69+
assert_eq!(greatest_common_divisor_recursive(-64, 32), 32);
70+
assert_eq!(greatest_common_divisor_recursive(-32, 64), 32);
71+
assert_eq!(greatest_common_divisor_recursive(-40, 40), 40);
72+
assert_eq!(greatest_common_divisor_recursive(12, -27), 3);
73+
}
74+
75+
#[test]
76+
fn mix_iterative() {
77+
assert_eq!(greatest_common_divisor_iterative(0, -5), 5);
78+
assert_eq!(greatest_common_divisor_iterative(-5, 0), 5);
79+
assert_eq!(greatest_common_divisor_iterative(-64, 32), 32);
80+
assert_eq!(greatest_common_divisor_iterative(-32, 64), 32);
81+
assert_eq!(greatest_common_divisor_iterative(-40, 40), 40);
82+
assert_eq!(greatest_common_divisor_iterative(12, -27), 3);
83+
}
84+
}

src/math/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
mod extended_euclidean_algorithm;
2+
mod greatest_common_divisor;
23
mod pascal_triangle;
34
mod perfect_numbers;
45
mod prime_check;
56
mod prime_numbers;
67
mod trial_division;
78

89
pub use self::extended_euclidean_algorithm::extended_euclidean_algorithm;
10+
pub use self::greatest_common_divisor::{
11+
greatest_common_divisor_iterative, greatest_common_divisor_recursive,
12+
};
913
pub use self::pascal_triangle::pascal_triangle;
1014
pub use self::perfect_numbers::perfect_numbers;
1115
pub use self::prime_check::prime_check;

0 commit comments

Comments
 (0)