Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added .github/workflows/ci.yml
Empty file.
6 changes: 6 additions & 0 deletions BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module(
name = "cpp-analytics-devops",
version = "1.0.0",
)

bazel_dep(name = "googletest", version = "1.17.0")
Empty file added LICENSE
Empty file.
Empty file added MODULE.bazel
Empty file.
Empty file added docker-compose.yaml
Empty file.
Empty file added docker/.dockerignore
Empty file.
Empty file added docker/Dockerfile
Empty file.
Empty file added docs/api.md
Empty file.
Empty file added docs/architecture.md
Empty file.
Empty file added k8s/configmap.yaml
Empty file.
Empty file added k8s/deployment.yaml
Empty file.
Empty file added k8s/hpa.yaml
Empty file.
Empty file added k8s/ingress.yaml
Empty file.
Empty file added k8s/secret.yaml
Empty file.
Empty file added k8s/service.yaml
Empty file.
20 changes: 20 additions & 0 deletions src/BUILD
Original file line number Diff line number Diff line change
@@ -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",
],
)
Empty file added src/api/BUILD
Empty file.
Empty file added src/api/rest.cpp
Empty file.
Empty file added src/api/rest.h
Empty file.
Empty file added src/api/utils.cpp
Empty file.
Empty file added src/api/utils.h
Empty file.
190 changes: 190 additions & 0 deletions src/factor.cpp
Original file line number Diff line number Diff line change
@@ -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<int64_t> Factorization::getAllFactors()
{
vector<int64_t> 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<int64_t> 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;
}
36 changes: 36 additions & 0 deletions src/factor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#ifndef FACTOR_H
#define FACTOR_H

#include <vector>
#include <iostream>
#include <cstdint>
#include <ctime>
#include <cmath>
#include <cstdlib>
#include <numeric>

using namespace std;

class Factorization
{
public:
Factorization(int64_t n);
~Factorization() = default;
vector<int64_t> 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
28 changes: 28 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -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;
}
8 changes: 8 additions & 0 deletions src/main.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef MAIN_H
#define MAIN_H

#include <iostream>
#include <stdexcept>
#include "factor.h"

#endif
Empty file added src/montecarlo.cpp
Empty file.
Empty file added src/montecarlo.h
Empty file.
Empty file added tests/BUILD
Empty file.
Empty file added tests/api_test.cpp
Empty file.
Empty file added tests/factor_test.cpp
Empty file.
Empty file added tests/montecarlo_test.cpp
Empty file.