diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..e69de29 diff --git a/BUILD b/BUILD new file mode 100644 index 0000000..8833729 --- /dev/null +++ b/BUILD @@ -0,0 +1,6 @@ +module( + name = "cpp-analytics-devops", + version = "1.0.0", +) + +bazel_dep(name = "googletest", version = "1.17.0") \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e69de29 diff --git a/MODULE.bazel b/MODULE.bazel new file mode 100644 index 0000000..e69de29 diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..e69de29 diff --git a/docker/.dockerignore b/docker/.dockerignore new file mode 100644 index 0000000..e69de29 diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..e69de29 diff --git a/docs/api.md b/docs/api.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..e69de29 diff --git a/k8s/configmap.yaml b/k8s/configmap.yaml new file mode 100644 index 0000000..e69de29 diff --git a/k8s/deployment.yaml b/k8s/deployment.yaml new file mode 100644 index 0000000..e69de29 diff --git a/k8s/hpa.yaml b/k8s/hpa.yaml new file mode 100644 index 0000000..e69de29 diff --git a/k8s/ingress.yaml b/k8s/ingress.yaml new file mode 100644 index 0000000..e69de29 diff --git a/k8s/secret.yaml b/k8s/secret.yaml new file mode 100644 index 0000000..e69de29 diff --git a/k8s/service.yaml b/k8s/service.yaml new file mode 100644 index 0000000..e69de29 diff --git a/src/BUILD b/src/BUILD new file mode 100644 index 0000000..a8965f0 --- /dev/null +++ b/src/BUILD @@ -0,0 +1,20 @@ +cc_library( + name = "factorLib", + srcs = [ + "factor.cpp" + ], + hdrs = [ + "factor.h" + ], +) + +cc_binary( + name = "mainProg", + srcs = [ + "main.cpp", + "main.h", + ], + deps = [ + ":factorLib", + ], +) \ No newline at end of file diff --git a/src/api/BUILD b/src/api/BUILD new file mode 100644 index 0000000..e69de29 diff --git a/src/api/rest.cpp b/src/api/rest.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/api/rest.h b/src/api/rest.h new file mode 100644 index 0000000..e69de29 diff --git a/src/api/utils.cpp b/src/api/utils.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/api/utils.h b/src/api/utils.h new file mode 100644 index 0000000..e69de29 diff --git a/src/factor.cpp b/src/factor.cpp new file mode 100644 index 0000000..e3db641 --- /dev/null +++ b/src/factor.cpp @@ -0,0 +1,190 @@ +#include "factor.h" + +using namespace std; + +// === member functions for Factorization === +/// @brief constructor +/// @param n the value for fatorization +Factorization::Factorization(int64_t n) : n(n) +{ + srand(time(0)); +} + +vector Factorization::getAllFactors() +{ + vector output = {}; + int64_t tmp = n; + while(tmp != 1) + { + auto factor = getFactor(tmp); + output.emplace_back(factor); + tmp = tmp / factor; + } + return output; +} + +/// @brief the main function to do the calculation +/// @return result +int64_t Factorization::getFactor(const int64_t& input) +{ + int64_t d = 1; + int64_t cnt = 0; + int64_t x = selectX0(input); + int64_t y = x; + + // trivial cases + if (input == 1 || input == 2 || input == 3) + return input; + else if (input%2 == 0) + { + return 2; + } + // check prime numbers + else if (millerRabin(input)) + { + return input; + } + + // must have a factor + while(d == 1 || d == input) + { + d = pollardsPho(x, y, input); + if (d == input) + { + failure++; + } + // basicLogging(x, y, d, cnt); + cnt++; + } + + if (!millerRabin(d)) + { + d = getFactor(d); + } + + return d; +} + +/// @brief basic iteration of the algorithm +/// @param x x +/// @param y y +/// @return d +int64_t Factorization::pollardsPho(int64_t &x, int64_t &y, const int64_t& input) +{ + selectC(c); + x = squareMod(x, c, input); + y = squareMod(squareMod(y, c, input), c, input); + return calculateD(x, y, input); +} + +/// @brief select the initial x +/// @return x +int64_t Factorization::selectX0(const int64_t& input) +{ + + int64_t output = (rand() % (input - 2)) + 2; + return output; +} + +/// @brief function to calculate f(x) = x^2 + c +/// @param x x +/// @param c c +/// @return f(x) +int64_t Factorization::squareMod(const int64_t& x, const int64_t& c, const int64_t& input) +{ + __int128_t output = (x * x + c) % input; + return output; +} + +/// @brief funtion to calculate D = gcd(abs(x-y), n) +int64_t Factorization::calculateD(const int64_t& x, const int64_t& y, const int64_t& input) +{ + return gcd(abs(x-y), input); +} + +/// @brief function to select c +/// @return c +void Factorization::selectC(int64_t& input) +{ + if (failure < 100) + input = 1; + else if (failure < 200) + input = 2; + else if (failure < 300) + input = 3; + // choose from [4, n) + else + input = (rand() % (n - 4)) + 4; +} + +/// @brief provides a basic logging showing info for x, y, d, cnt +/// @param x x +/// @param y y +/// @param d d +/// @param cnt cnt +void Factorization::basicLogging(const int64_t &x, const int64_t &y, const int64_t &d, const int64_t &cnt) +{ + cout << cnt << ":" << endl; + cout << "x, y, d: " << x << "," << y << "," << d << endl; +} + +/// @brief function to check prime (in the cases of none 1, 2, 3 or even) +/// @return bool result +bool Factorization::millerRabin(const int64_t& input) +{ + int64_t d = input - 1; + int64_t s = 0; + while(d % 2 == 0) + { + d /= 2; + s++; + } + + // enough for 64 bit int + vector bases = {2,3,5,7,11,13,17}; + for(const auto& base : bases) + { + if (base >= input) + continue; + + // calculate x = a^d % n + __int128_t x = mod_pow(base, d, input); + + if (x == 1 || x == input - 1) + continue; + + bool passed = false; + for(int64_t i = 1; i < s; i++) + { + x = x * x % input; + if (x == input - 1) + { + passed = true; + break; + } + } + if (!passed) + return false; + } + return true; +} + +/// @brief internal function to calculate mod power +/// @param b b +/// @param d d +/// @return mod power result +int64_t Factorization::mod_pow(const int64_t& b, const int64_t& d, const int64_t& input) +{ + __int128_t result = 1; + int64_t base = b; + int64_t dd = d; + base = base % input; + while(dd > 0) + { + if (dd % 2 == 1) + result = (result * base) % input; + base = base * base % input; + dd /= 2; + } + return result; +} \ No newline at end of file diff --git a/src/factor.h b/src/factor.h new file mode 100644 index 0000000..d1a1497 --- /dev/null +++ b/src/factor.h @@ -0,0 +1,36 @@ +#ifndef FACTOR_H +#define FACTOR_H + +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +class Factorization +{ +public: + Factorization(int64_t n); + ~Factorization() = default; + vector getAllFactors(); + int64_t getFactor(const int64_t& input); + +private: + int64_t n; + int64_t c; + int64_t failure = 0; + int64_t squareMod(const int64_t& x, const int64_t& c, const int64_t& input); + int64_t calculateD(const int64_t& x, const int64_t& y, const int64_t& input); + void selectC(int64_t& input); + int64_t selectX0(const int64_t& input); + int64_t pollardsPho(int64_t &x, int64_t &y, const int64_t& input); + bool millerRabin(const int64_t& input); + int64_t mod_pow(const int64_t& b, const int64_t& d, const int64_t& input); + void basicLogging(const int64_t &x, const int64_t &y, const int64_t &d, const int64_t &cnt); +}; + +#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..f084620 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,28 @@ +#include "main.h" + +using namespace std; + +int main(int argc, char** argv) +{ + string input = ""; + if (argc > 1) + input = argv[1]; + else + { + throw invalid_argument("No argument is passed!"); + } + + // might throw std::invalid_argument or std::out_of_range in case not able to parse + int64_t n = stoll(input); + + auto factorization = Factorization(n); + + cout << "Factors of " << n << " are: " << endl; + auto results = factorization.getAllFactors(); + + for(const auto& result : results) + { + cout << result << ","; + } + cout << endl; +} \ No newline at end of file diff --git a/src/main.h b/src/main.h new file mode 100644 index 0000000..8f38a45 --- /dev/null +++ b/src/main.h @@ -0,0 +1,8 @@ +#ifndef MAIN_H +#define MAIN_H + +#include +#include +#include "factor.h" + +#endif \ No newline at end of file diff --git a/src/montecarlo.cpp b/src/montecarlo.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/montecarlo.h b/src/montecarlo.h new file mode 100644 index 0000000..e69de29 diff --git a/tests/BUILD b/tests/BUILD new file mode 100644 index 0000000..e69de29 diff --git a/tests/api_test.cpp b/tests/api_test.cpp new file mode 100644 index 0000000..e69de29 diff --git a/tests/factor_test.cpp b/tests/factor_test.cpp new file mode 100644 index 0000000..e69de29 diff --git a/tests/montecarlo_test.cpp b/tests/montecarlo_test.cpp new file mode 100644 index 0000000..e69de29