diff options
Diffstat (limited to 'gcd.cpp')
-rw-r--r-- | gcd.cpp | 89 |
1 files changed, 47 insertions, 42 deletions
@@ -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; +} |