Skip to content

Commit 2d5f815

Browse files
committed
Added math algorithms
1 parent e2a2b6b commit 2d5f815

File tree

5 files changed

+414
-0
lines changed

5 files changed

+414
-0
lines changed

src/main/cpp/algorithms/math/GCD.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* @file GCD.h
3+
* @author (original JAVA) William Fiset, [email protected]
4+
* (conversion to C++) Armin Zare Zadeh, [email protected]
5+
* @date 15 July 2020
6+
* @version 0.1
7+
* @brief An implementation of finding the GCD of two numbers
8+
*
9+
* <p>Time Complexity ~O(log(a + b))
10+
*/
11+
12+
#ifndef D_GCD_H
13+
#define D_GCD_H
14+
15+
#include <vector>
16+
#include <deque>
17+
#include <list>
18+
#include <set> // set and multiset
19+
#include <map> // map and multimap
20+
#include <unordered_set> // unordered set/multiset
21+
#include <unordered_map> // unordered map/multimap
22+
#include <iterator>
23+
#include <algorithm>
24+
#include <numeric> // some numeric algorithm
25+
#include <functional>
26+
#include <stack>
27+
28+
#include <sstream>
29+
#include <memory>
30+
#include <iostream>
31+
#include <cmath>
32+
33+
namespace dsa {
34+
35+
class GCD {
36+
public:
37+
// Computes the Greatest Common Divisor (GCD) of a & b
38+
// This method ensures that the value returned is non negative
39+
static long gcd(long a, long b) {
40+
return b == 0 ? (a < 0 ? -a : a) : gcd(b, a % b);
41+
}
42+
};
43+
44+
45+
void GCD_test()
46+
{
47+
std::cout << GCD::gcd(12, 18) << std::endl; // 6
48+
std::cout << GCD::gcd(-12, 18) << std::endl; // 6
49+
std::cout << GCD::gcd(12, -18) << std::endl; // 6
50+
std::cout << GCD::gcd(-12, -18) << std::endl; // 6
51+
52+
std::cout << GCD::gcd(5, 0) << std::endl; // 5
53+
std::cout << GCD::gcd(0, 5) << std::endl; // 5
54+
std::cout << GCD::gcd(-5, 0) << std::endl; // 5
55+
std::cout << GCD::gcd(0, -5) << std::endl; // 5
56+
std::cout << GCD::gcd(0, 0) << std::endl; // 0
57+
}
58+
59+
} // namespace dsa
60+
61+
#endif /* D_GCD_H */
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* @file IsPrime.h
3+
* @author (original JAVA) Micah Stairs, William Fiset, [email protected]
4+
* (conversion to C++) Armin Zare Zadeh, [email protected]
5+
* @date 15 July 2020
6+
* @version 0.1
7+
* @brief Tests whether a number is a prime number or not Time Complexity: O(sqrt(n))
8+
*/
9+
10+
#ifndef D_ISPRIME_H
11+
#define D_ISPRIME_H
12+
13+
#include <vector>
14+
#include <deque>
15+
#include <list>
16+
#include <set> // set and multiset
17+
#include <map> // map and multimap
18+
#include <unordered_set> // unordered set/multiset
19+
#include <unordered_map> // unordered map/multimap
20+
#include <iterator>
21+
#include <algorithm>
22+
#include <numeric> // some numeric algorithm
23+
#include <functional>
24+
#include <stack>
25+
26+
#include <sstream>
27+
#include <memory>
28+
#include <iostream>
29+
#include <cmath>
30+
31+
namespace dsa {
32+
33+
class IsPrime {
34+
public:
35+
static bool isPrime(long n) {
36+
if (n < 2) return false;
37+
if (n == 2 || n == 3) return true;
38+
if (n % 2 == 0 || n % 3 == 0) return false;
39+
40+
long limit = (long) sqrt(n);
41+
42+
for (long i = 5; i <= limit; i += 6) {
43+
if (n % i == 0 || n % (i + 2) == 0) {
44+
return false;
45+
}
46+
}
47+
return true;
48+
}
49+
50+
};
51+
52+
53+
void IsPrime_test()
54+
{
55+
std::cout << IsPrime::isPrime(5) << std::endl;
56+
std::cout << IsPrime::isPrime(31) << std::endl;
57+
std::cout << IsPrime::isPrime(1433) << std::endl;
58+
std::cout << IsPrime::isPrime(8763857775536878331L) << std::endl;
59+
}
60+
61+
} // namespace dsa
62+
63+
#endif /* D_ISPRIME_H */

src/main/cpp/algorithms/math/LCM.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* @file LCM.h
3+
* @author (original JAVA) William Fiset, [email protected]
4+
* (conversion to C++) Armin Zare Zadeh, [email protected]
5+
* @date 15 July 2020
6+
* @version 0.1
7+
* @brief An implementation of finding the LCM of two numbers
8+
*
9+
* <p>Time Complexity ~O(log(a + b))
10+
*/
11+
12+
#ifndef D_LCM_H
13+
#define D_LCM_H
14+
15+
#include <vector>
16+
#include <deque>
17+
#include <list>
18+
#include <set> // set and multiset
19+
#include <map> // map and multimap
20+
#include <unordered_set> // unordered set/multiset
21+
#include <unordered_map> // unordered map/multimap
22+
#include <iterator>
23+
#include <algorithm>
24+
#include <numeric> // some numeric algorithm
25+
#include <functional>
26+
#include <stack>
27+
28+
#include <sstream>
29+
#include <memory>
30+
#include <iostream>
31+
#include <cmath>
32+
33+
namespace dsa {
34+
35+
class LCM {
36+
private:
37+
// Finds the greatest common divisor of a and b
38+
static long gcd(long a, long b) {
39+
return b == 0 ? (a < 0 ? -a : a) : gcd(b, a % b);
40+
}
41+
42+
public:
43+
// Finds the least common multiple of a and b
44+
static long lcm(long a, long b) {
45+
long lcm = (a / gcd(a, b)) * b;
46+
return lcm > 0 ? lcm : -lcm;
47+
}
48+
};
49+
50+
51+
void LCM_test()
52+
{
53+
std::cout << LCM::lcm(12, 18) << std::endl; // 36
54+
std::cout << LCM::lcm(-12, 18) << std::endl; // 36
55+
std::cout << LCM::lcm(12, -18) << std::endl; // 36
56+
std::cout << LCM::lcm(-12, -18) << std::endl; // 36
57+
}
58+
59+
} // namespace dsa
60+
61+
#endif /* D_LCM_H */
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/*
2+
* @file PrimeFactorization.h
3+
* @author (original JAVA) William Fiset, [email protected]
4+
* (conversion to C++) Armin Zare Zadeh, [email protected]
5+
* @date 15 July 2020
6+
* @version 0.1
7+
* @brief An implementation of finding the LCM of two numbers
8+
*
9+
*/
10+
11+
#ifndef D_PRIMEFACTORIZATION_H
12+
#define D_PRIMEFACTORIZATION_H
13+
14+
#include <vector>
15+
#include <deque>
16+
#include <queue>
17+
#include <list>
18+
#include <set> // set and multiset
19+
#include <map> // map and multimap
20+
#include <unordered_set> // unordered set/multiset
21+
#include <unordered_map> // unordered map/multimap
22+
#include <iterator>
23+
#include <algorithm>
24+
#include <numeric> // some numeric algorithm
25+
#include <functional>
26+
#include <stack>
27+
28+
#include <chrono>
29+
#include <random>
30+
#include <sstream>
31+
#include <memory>
32+
#include <iostream>
33+
#include <cmath>
34+
35+
namespace dsa {
36+
37+
38+
class PrimeFactorization {
39+
40+
public:
41+
static std::multiset<long> primeFactorization(long n) {
42+
std::multiset<long> factors;
43+
if (n <= 0) throw std::invalid_argument("Invalid input");
44+
else if (n == 1) return factors;
45+
auto longComparer = [](long a, long b) -> bool { return a > b; };
46+
std::priority_queue<long, std::vector<long>, decltype(longComparer)> divisorQueue(longComparer);
47+
divisorQueue.push(n);
48+
while (divisorQueue.size() > 0) {
49+
long divisor = divisorQueue.top();
50+
divisorQueue.pop();
51+
if (isPrime(divisor)) {
52+
factors.insert(divisor);
53+
continue;
54+
}
55+
long next_divisor = pollardRho(divisor);
56+
if (next_divisor == divisor) {
57+
divisorQueue.push(divisor);
58+
} else {
59+
divisorQueue.push(next_divisor);
60+
divisorQueue.push(divisor / next_divisor);
61+
}
62+
}
63+
return factors;
64+
}
65+
66+
private:
67+
68+
static int genRandInt(int start_in, int end_in)
69+
{
70+
// engine only provides a source of randomness
71+
std::mt19937_64 rng;
72+
// initialize the random number generator with time-dependent seed
73+
uint64_t timeSeed = std::chrono::high_resolution_clock::now().time_since_epoch().count();
74+
std::seed_seq ss{uint32_t(timeSeed & 0xffffffff), uint32_t(timeSeed>>32)};
75+
rng.seed(ss);
76+
std::uniform_int_distribution<int> dist(start_in, end_in);
77+
78+
return dist(rng);
79+
}
80+
81+
82+
static long pollardRho(long n) {
83+
if (n % 2 == 0) return 2;
84+
long x = 2 + (long) genRandInt(0, 999999);
85+
long c = 2 + (long) genRandInt(0, 999999);
86+
long y = x;
87+
long d = 1;
88+
while (d == 1) {
89+
x = (x * x + c) % n;
90+
y = (y * y + c) % n;
91+
y = (y * y + c) % n;
92+
d = gcd(abs(x - y), n);
93+
if (d == n) break;
94+
}
95+
return d;
96+
}
97+
98+
99+
static long gcd(long a, long b) {
100+
return b == 0 ? a : gcd(b, a % b);
101+
}
102+
103+
104+
static bool isPrime(long n) {
105+
if (n < 2) return false;
106+
if (n == 2 || n == 3) return true;
107+
if (n % 2 == 0 || n % 3 == 0) return false;
108+
long limit = (long) sqrt(n);
109+
for (long i = 5; i <= limit; i += 6) if (n % i == 0 || n % (i + 2) == 0) return false;
110+
return true;
111+
}
112+
113+
};
114+
115+
116+
void PrimeFactorization_test()
117+
{
118+
#define PRINT_FACTORIZATION(r) \
119+
do { \
120+
std::cout << "["; \
121+
for (auto pf : PrimeFactorization::primeFactorization(r)) std::cout << pf << ","; \
122+
std::cout << "]"; \
123+
} while(0)
124+
125+
PRINT_FACTORIZATION(7); // [7]
126+
PRINT_FACTORIZATION(100); // [2,2,5,5]
127+
PRINT_FACTORIZATION(666); // [2,3,3,37]
128+
PRINT_FACTORIZATION(872342345); // [5, 7, 7, 67, 19, 2797]
129+
}
130+
131+
} // namespace dsa
132+
133+
#endif /* D_PRIMEFACTORIZATION_H */

0 commit comments

Comments
 (0)