summaryrefslogtreecommitdiff
path: root/gcd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gcd.cpp')
-rw-r--r--gcd.cpp89
1 files changed, 47 insertions, 42 deletions
diff --git a/gcd.cpp b/gcd.cpp
index 659c77a..e1d363a 100644
--- a/gcd.cpp
+++ b/gcd.cpp
@@ -7,65 +7,70 @@
*
*
* To use GNU Multiple Precision Arithmetic Library:
- *
- * # g++ -o gcd-cpp-gmp -DGMP -lgmpxx -lgmp gcd.cpp
+ *
+ * # g++ -DGMP gcd.cpp -lgmpxx -lgmp -o gcd-cpp-gmp
* # ./gcd-cpp-gmp 1234567890987654321 987654321234567
* # 63
*
*/
-
#include <cstdlib>
#include <iostream>
-#include <vector>
#include <sstream>
-
-using namespace std;
+#include <vector>
+#if __cplusplus >= 201703L
+#include <execution>
+#include <numeric>
+#endif
#ifdef GMP
- #include <gmpxx.h>
- typedef mpz_class Number;
+#include <gmpxx.h>
+typedef mpz_class Number;
#else
- typedef unsigned int Number;
-#endif // GMP
+typedef unsigned long Number;
+#endif
-typedef vector<Number> Numbers;
+using std::vector;
-Number gcd(Number a, Number b)
-{
- Number c;
- while (b != 0) {
- c = b;
- b = a % b;
- a = c;
- }
- return a;
+template <class N> N gcd2(N a, N b) {
+ while (b != 0) {
+ N c = b;
+ b = a % b;
+ a = c;
+ }
+ return a;
}
-Number gcd(const Numbers & ns)
-{
- Number r = 0;
- for(Numbers::const_iterator n = ns.begin(); n != ns.end(); ++n)
- r = gcd(*n, r);
- return r;
+#if __cplusplus >= 201703L
+template <class N> class GCD {
+public:
+ N operator()(N a, N b) const { return gcd2(a, b); };
+};
+
+template <class N> N gcd(const vector<N> &ns) {
+ GCD<N> GCD;
+ return reduce(std::execution::par, begin(ns), end(ns), N(0), GCD);
}
+#else
-int main (int argc, char *argv[])
-{
- if (argc > 1) {
- Numbers ns(argc - 1);
- for(int n = 1; n < argc; ++n) {
- stringstream str;
- str << argv[n];
- str >> ns[n-1];
- /* NOTE:
- * For GMP we can just assign: ns[n-1] = argv[n],
- * and sstream is not needed.
- */
- }
- cout << gcd(ns) << endl;
- }
- return EXIT_SUCCESS;
+template <class N> N gcd(const vector<N> &ns) {
+ N r = 0;
+ for (typename vector<N>::const_iterator n = ns.begin(); n != ns.end(); ++n)
+ r = gcd2(*n, r);
+ return r;
}
+#endif
+int main(int argc, char *argv[]) {
+ if (argc > 1) {
+ vector<Number> ns(argc - 1);
+ for (int n = 1; n < argc; ++n) {
+ std::stringstream str;
+ str << argv[n];
+ str >> ns[n - 1];
+ }
+ std::cout << gcd(ns) << std::endl;
+ }
+ return EXIT_SUCCESS;
+}