5
5
* @details
6
6
* The GCD of n numbers can be calculated by
7
7
* repeatedly calculating the GCDs of pairs of numbers
8
- * i.e. gcd(a, b, c) = gcd(gcd(a, b), c)
9
- * Euclidean algorithm helps calculate the GCD of each pair of numbers efficiently
10
- *
8
+ * i.e. \f$\gcd(a, b, c)\f$ = \f$\gcd(\gcd(a, b), c)\f$
9
+ * Euclidean algorithm helps calculate the GCD of each pair of numbers
10
+ * efficiently
11
+ *
11
12
* @see gcd_iterative_euclidean.cpp, gcd_recursive_euclidean.cpp
12
13
*/
14
+ #include < algorithm> // / for std::abs
15
+ #include < array> // / for std::array
16
+ #include < cassert> // / for assert
13
17
#include < iostream> // / for IO operations
14
- #include < cassert> // / for assert
15
- #include < algorithm> // / for std::abs
16
18
17
19
/* *
18
20
* @namespace math
@@ -31,10 +33,12 @@ namespace gcd_of_n_numbers {
31
33
* @return GCD of x and y via recursion
32
34
*/
33
35
int gcd_two (int x, int y) {
34
- // base cases
35
- if (y == 0 ) return x;
36
- if (x == 0 ) return y;
37
- return gcd_two (y, x % y); // Euclidean method
36
+ // base cases
37
+ if (y == 0 )
38
+ return x;
39
+ if (x == 0 )
40
+ return y;
41
+ return gcd_two (y, x % y); // Euclidean method
38
42
}
39
43
/* *
40
44
* @brief Function to check if all elements in array are 0
@@ -43,37 +47,37 @@ int gcd_two(int x, int y) {
43
47
* @return 'True' if all elements are 0
44
48
* @return 'False' if not all elements are 0
45
49
*/
46
- bool check_all_zeros (int a[], size_t n) {
47
- // Check for the undefined GCD cases
48
- int zero_count = 0 ;
49
- for (int i = 0 ; i < n; ++i) {
50
- if (a[i] == 0 ) {
51
- ++zero_count;
52
- }
50
+ template <size_t n> bool check_all_zeros (std::array<int , n> a) {
51
+ // Check for the undefined GCD cases
52
+ int zero_count = 0 ;
53
+ for (int i = 0 ; i < n; ++i) {
54
+ if (a[i] == 0 ) {
55
+ ++zero_count;
53
56
}
57
+ }
54
58
55
- // return whether all elements in array are 0
56
- return zero_count == n;
59
+ // return whether all elements in array are 0
60
+ return zero_count == n;
57
61
}
58
- /* *
59
- * @brief Main program to compute GCD using division algorithm
62
+ /* *
63
+ * @brief Main program to compute GCD by repeatedly use Euclidean algorithm
60
64
* @param a Array of integers to compute GCD for
61
- * @param n number of integers in the array
65
+ * @param n Number of integers in the array
62
66
* @return GCD of the numbers in the array
63
67
*/
64
- int gcd (int a[], size_t n ) {
65
- // GCD is undefined if all elements in the array are 0
66
- if (check_all_zeros (a, n ))
67
- return -1 ; // since gcd is positive, use -1 to mark undefined gcd
68
+ template < size_t n> int gcd (std::array< int , n> a ) {
69
+ // GCD is undefined if all elements in the array are 0
70
+ if (check_all_zeros (a))
71
+ return -1 ; // since gcd is positive, use -1 to mark undefined gcd
68
72
69
- int gcd = a[0 ];
70
- for (int i = 1 ; i < n; i++) {
71
- gcd = gcd_two (gcd, a[i]);
72
- if (std::abs (gcd) == 1 )
73
- break ; // if gcd is already 1, further computations still result in gcd of 1
74
- }
73
+ int gcd = a[0 ];
74
+ for (int i = 1 ; i < n; i++) {
75
+ gcd = gcd_two (gcd, a[i]);
76
+ if (std::abs (gcd) == 1 )
77
+ break ; // gcd is already 1, further computations still result in gcd of 1
78
+ }
75
79
76
- return std::abs (gcd); // divisors can be negative, and we only want positive value
80
+ return std::abs (gcd); // divisors can be negative, we only want positive value
77
81
}
78
82
} // namespace gcd_of_n_numbers
79
83
} // namespace math
@@ -82,31 +86,31 @@ int gcd(int a[], size_t n) {
82
86
* @brief Self-test implementation
83
87
* @return void
84
88
*/
85
- static void test () {
86
- int array_1[ 1 ] = {0 };
87
- int array_2[ 1 ] = {1 };
88
- int array_3[ 2 ] = {0 , 2 };
89
- int array_4[ 3 ] = {-60 , 24 , 18 };
90
- int array_5[ 4 ] = {100 , -100 , -100 , 200 };
91
- int array_6[ 5 ] = {0 , 0 , 0 , 0 , 0 };
92
- int array_7[ 7 ] = {90 , -120 , 0 , 135 , 660 , -280 , 900 };
93
- int array_8[ 7 ] = {90 , -120 , 0 , 4000 , 0 , 0 , 111 };
89
+ static void test () {
90
+ std::array< int , 1 > array_1 = {0 };
91
+ std::array< int , 1 > array_2 = {1 };
92
+ std::array< int , 2 > array_3 = {0 , 2 };
93
+ std::array< int , 3 > array_4 = {-60 , 24 , 18 };
94
+ std::array< int , 4 > array_5 = {100 , -100 , -100 , 200 };
95
+ std::array< int , 5 > array_6 = {0 , 0 , 0 , 0 , 0 };
96
+ std::array< int , 7 > array_7 = {10350 , -24150 , 0 , 17250 , 37950 , -127650 , 51750 };
97
+ std::array< int , 7 > array_8 = {9500000 , -12121200 , 0 , 4444 , 0 , 0 , 123456789 };
94
98
95
- assert (math::gcd_of_n_numbers::gcd (array_1, 1 ) == -1 );
96
- assert (math::gcd_of_n_numbers::gcd (array_2, 1 ) == 1 );
97
- assert (math::gcd_of_n_numbers::gcd (array_3, 2 ) == 2 );
98
- assert (math::gcd_of_n_numbers::gcd (array_4, 3 ) == 6 );
99
- assert (math::gcd_of_n_numbers::gcd (array_5, 4 ) == 100 );
100
- assert (math::gcd_of_n_numbers::gcd (array_6, 5 ) == -1 );
101
- assert (math::gcd_of_n_numbers::gcd (array_7, 7 ) == 5 );
102
- assert (math::gcd_of_n_numbers::gcd (array_8, 7 ) == 1 );
99
+ assert (math::gcd_of_n_numbers::gcd (array_1) == -1 );
100
+ assert (math::gcd_of_n_numbers::gcd (array_2) == 1 );
101
+ assert (math::gcd_of_n_numbers::gcd (array_3) == 2 );
102
+ assert (math::gcd_of_n_numbers::gcd (array_4) == 6 );
103
+ assert (math::gcd_of_n_numbers::gcd (array_5) == 100 );
104
+ assert (math::gcd_of_n_numbers::gcd (array_6) == -1 );
105
+ assert (math::gcd_of_n_numbers::gcd (array_7) == 3450 );
106
+ assert (math::gcd_of_n_numbers::gcd (array_8) == 1 );
103
107
}
104
108
105
109
/* *
106
110
* @brief Main function
107
111
* @return 0 on exit
108
112
*/
109
113
int main () {
110
- test (); // run self-test implementation
111
- return 0 ;
114
+ test (); // run self-test implementation
115
+ return 0 ;
112
116
}
0 commit comments