Skip to content

Commit

Permalink
Merge pull request #50 from emperor-2001/main
Browse files Browse the repository at this point in the history
Miller Rabbin Primality Test Added in Math section
  • Loading branch information
skully-coder committed Oct 2, 2021
2 parents 618b008 + 344dcfa commit 2540cfe
Show file tree
Hide file tree
Showing 2 changed files with 188 additions and 0 deletions.
142 changes: 142 additions & 0 deletions Math/MillerRabbin_PrimalityTest/MillerRabbin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
#include<bits/stdc++.h>
using namespace std;
#define gc getchar_unlocked
#define fo(i,n) for(i=0;i<n;i++)
#define Fo(i,k,n) for(i=k;k<n?i<n:i>n;k<n?i+=1:i-=1)
#define ll unsigned long long
#define si(x) scanf("%d",&x)
#define sl(x) scanf("%lld",&x)
#define ss(s) scanf("%s",s)
#define pi(x) printf("%d\n",x)
#define pl(x) printf("%lld\n",x)
#define ps(s) printf("%s\n",s)
#define deb(x) cout << #x << "=" << x << endl
#define deb2(x, y) cout << #x << "=" << x << "," << #y << "=" << y << endl
#define pb push_back
#define mp make_pair
#define F first
#define S second
#define all(x) x.begin(), x.end()
#define clr(x) memset(x, 0, sizeof(x))
#define sortall(x) sort(all(x))
#define tr(it, a) for(auto it = a.begin(); it != a.end(); it++)
#define PI 3.1415926535897932384626
typedef pair<int, int> pii;
typedef pair<ll, ll> pl;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vpii;
typedef vector<pl> vpl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
mt19937_64 rang(chrono::high_resolution_clock::now().time_since_epoch().count());
int rng(int lim) {
uniform_int_distribution<int> uid(0,lim-1);
return uid(rang);
}
int mpow(int base, int exp);
void ipgraph(int n, int m);
void dfs(int u, int par);


const int N = 3e5, M = N;
//=======================

//vi g[N];
//int a[N];
ll mulMod(ll a, ll b, ll mod)
{
ll x=0,y=a%mod;
while(b>0)
{
if(b%2==1)
x= (x+y)%mod;

y= (y*2LL)%mod;
b/=2;
}

return (x%mod);

}

ll binPower(ll a, ll n, ll c)
{

ll res=1;
while(n)
{
if(n & 1)
res= (res*a)%c;

n>>=1;
a= (a*a)%c;

}

return res%c;
}


bool checkComposite(ll a , ll n , int s, ll d)
{
ll x = binPower(a,d,n);
if(x == 1 || x == n-1)
return false;

for(int i=1;i<s;i++)
{
x = (x*x)%n;
if(x== n-1)
return false;
}
return true;
}


bool isPrime(ll n)
{
if(n<2)
return false;

ll d=n-1;
int s=0;
while((d & 1)==0)
{
d>>=1;
s++;
}

for(ll a : {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37})
{
if(n==a)
return true;

if(checkComposite(a,n,s,d))
return false;
}
return true;

}

int main() {
ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
srand(chrono::high_resolution_clock::now().time_since_epoch().count());

ll t = 1;
cin >> t;
while(t--) {

ll n;
cin >> n;
if(isPrime(n))
cout << "YES" << "\n";
else
cout << "NO" << "\n";


}

return 0;
}

46 changes: 46 additions & 0 deletions Math/MillerRabbin_PrimalityTest/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Problem Statement
For a given number N check if it is prime or not. A prime number is a number which is only divisible by 1 and itself.

## Input Format

you will be given an integer of maximum 64 bit N

## Constraints
```
Expected Time Complexity: O(sqrt(N))
Expected Space Complexity: O(1)
1 <= N <= 10^9
```
## Output Format

```
YES OR NO
```
## Sample Input
```
N = 5
```
## Sample Output
```
YES
```
## Explanation
```
The Miller-Rabin test extends the ideas from the Fermat test.
For an odd number n, n−1 is even and we can factor out all powers of 2. We can write:
If n is prime, then n has to divide one of these factors. And in the Miller-Rabin primality test we check exactly that statement, which is a more stricter version of the statement of the Fermat test. For a base 2≤a≤n−2 we check if either
ad≡1modn
holds or
a2rd≡−1modn
holds for some 0≤r≤s−1.
If we found a base a which doesn't satisfy any of the above equalities, than we found a witness for the compositeness of n. In this case we have proven that n is not a prime number.
Similar to the Fermat test, it is also possible that the set of equations is satisfied for a composite number. In that case the base a is called a strong liar. If a base a satisfies the equations (one of them), n is only strong probable prime. However, there are no numbers like the Carmichael numbers, where all non-trivial bases lie. In fact it is possible to show, that at most 14 of the bases can be strong liars. If n is composite, we have a probability of ≥75% that a random base will tell us that it is composite. By doing multiple iterations, choosing different random bases, we can tell with very high probability if the number is truly prime or if it is composite.
```

3 comments on commit 2540cfe

@skully-coder
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CodeFactor found an issue: Use of scanf() operation that permits buffer overflows (CWE-120)

It's currently on:
Math\MillerRabbin_PrimalityTest\MillerRabbin.cpp:9
Commit 2540cfe

@skully-coder
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CodeFactor found an issue: Redundant blank line at the end of a code block should be deleted.

It's currently on:
Math\MillerRabbin_PrimalityTest\MillerRabbin.cpp:137
Commit 2540cfe

@skully-coder
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CodeFactor found an issue: Redundant blank line at the start of a code block should be deleted.

It's currently on:
Math\MillerRabbin_PrimalityTest\MillerRabbin.cpp:129
Commit 2540cfe

Please sign in to comment.