Skip to content

Commit b0ed8b5

Browse files
authored
Merge pull request #227 from Priyangshuyogi/myone
Chinese Remainder Theorem in cpp
2 parents eb66adf + 03f4e6f commit b0ed8b5

File tree

4 files changed

+249
-0
lines changed

4 files changed

+249
-0
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
Given two integers ‘a’ and ‘m’, find modular multiplicative inverse of ‘a’ under modulo ‘m’.
2+
3+
The modular multiplicative inverse is an integer ‘x’ such that.
4+
5+
a x ≡ 1 (mod m)
6+
7+
The value of x should be in {0, 1, 2, … m-1}, i.e., in the ring of integer modulo m.
8+
9+
The multiplicative inverse of “a modulo m” exists if and only if a and m are relatively prime (i.e., if gcd(a, m) = 1).
10+
11+
Examples:
12+
13+
Input: a = 3, m = 11
14+
15+
Output: 4
16+
17+
Since (4x3) mod 11 = 1,
18+
4 is modulo inverse of 3
19+
20+
One might think, 15 also as a valid output as "(15x3) mod 11"
21+
is also 1, but 15 is not in ring {0, 1, 2, ... 10}, so not
22+
valid.
23+
24+
Input: a = 10, m = 17
25+
26+
Output: 12
27+
28+
Since (10x12) mod 17 = 1, 12 is modulo inverse of 3
29+
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
The Chinese remainder theorem is a theorem of number theory, which states that if one knows the remainders of the Euclidean division of an
2+
integer n by several integers, then one can determine uniquely the remainder of the division of n by the product of these integers, under
3+
the condition that the divisors are pairwise coprime.
4+
SAY.........
5+
We are given two arrays num[0..k-1] and rem[0..k-1].
6+
In num[0..k-1], every pair is coprime (gcd for every pair is 1).We need to find minimum positive number x such that:
7+
8+
x % num[0] = rem[0],
9+
x % num[1] = rem[1],
10+
.......................
11+
x % num[k-1] = rem[k-1]
12+
13+
Basically, we are given k numbers which are pairwise coprime, and given remainders of these numbers when an unknown number x is divided
14+
by them. We need to find the minimum possible value of x that produces given remainders.
15+
16+
Examples:
17+
18+
Input: num[] = {5, 7}, rem[] = {1, 3}
19+
20+
Output: 31
21+
22+
Explanation:
23+
24+
31 is the smallest number such that:
25+
26+
(1) When we divide it by 5, we get remainder 1.
27+
28+
(2) When we divide it by 7, we get remainder 3.
29+
30+
Input: num[] = {3, 4, 5}, rem[] = {2, 3, 1}
31+
32+
Output: 11
33+
34+
Explanation:
35+
36+
11 is the smallest number such that:
37+
38+
(1) When we divide it by 3, we get remainder 2.
39+
40+
(2) When we divide it by 4, we get remainder 3.
41+
42+
(3) When we divide it by 5, we get remainder 1.
43+
44+
//////// The solution is based on below formula.\\\\\\\\\\\\
45+
46+
47+
x = ( ∑ (rem[i]*pp[i]*inv[i]) ) % prod
48+
Where 0 <= i <= n-1
49+
50+
rem[i] is given array of remainders
51+
52+
prod is product of all given numbers
53+
prod = num[0] * num[1] * ... * num[k-1]
54+
55+
pp[i] is product of all but num[i]
56+
pp[i] = prod / num[i]
57+
58+
inv[i] = Modular Multiplicative Inverse of pp[i] with respect to num[i]
59+
60+
/// I have explained the Modular multiplicative inverse method by Extended Euclidean algorithms in another file
61+
(Named : Modular multiplicative inverse).///
62+
63+
///////WORKING PROCESS\\\\\\\
64+
65+
Example:
66+
67+
Let us take below example to understand the solution
68+
69+
num[] = {3, 4, 5}
70+
71+
rem[] = {2, 3, 1}
72+
73+
prod = 60
74+
75+
pp[] = {20, 15, 12}
76+
77+
inv[] = {2, 3, 3} { (20X2)%3 = 1, (15X3)%4 = 1
78+
(12X3)%5 = 1}
79+
80+
x = (rem[0]*pp[0]*inv[0] + rem[1]*pp[1]*inv[1] + rem[2]*pp[2]*inv[2]) % prod
81+
82+
= (2*20*2 + 3*15*3 + 1*12*3) % 60
83+
84+
= (40 + 135 + 36) % 60
85+
86+
= 11
87+
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
Below is C++ implementation of above formula. We can use Extended Euclid based method(Described in the folder) discussed here to find inverse modulo.
2+
3+
// A C++ program to demonstrate working of Chinise remainder Theorem
4+
5+
// Returns modulo inverse of a with respect to m using extended Euclid Algorithm.
6+
7+
#include<bits/stdc++.h>
8+
using namespace std;
9+
int inv(int a, int m)
10+
{
11+
int m0 = m, t, q;
12+
int x0 = 0, x1 = 1;
13+
14+
if (m == 1)
15+
return 0;
16+
17+
// Application of extended Euclid Algorithm
18+
while (a > 1)
19+
{
20+
// q is quotient
21+
q = a / m;
22+
23+
t = m;
24+
25+
// m is remainder
26+
m = a % m, a = t;
27+
28+
t = x0;
29+
30+
x0 = x1 - q * x0;
31+
32+
x1 = t;
33+
}
34+
35+
// Make x1 positive
36+
if (x1 < 0)
37+
x1 += m0;
38+
39+
return x1;
40+
}
41+
42+
// k is size of num[] and rem[]. Returns the smallest
43+
// number x such that:
44+
// x % num[0] = rem[0],
45+
// x % num[1] = rem[1],
46+
// ..................
47+
// x % num[k-2] = rem[k-1]
48+
// Assumption: Numbers in num[] are pairwise coprime i.e(gcd for every pair is 1)
49+
50+
int findMinX(int num[], int rem[], int k)
51+
{
52+
// Compute product of all numbers
53+
int prod = 1;
54+
for (int i = 0; i < k; i++)
55+
prod *= num[i];
56+
57+
// Initialize result
58+
int result = 0;
59+
60+
// Apply above formula
61+
for (int i = 0; i < k; i++)
62+
{
63+
int pp = prod / num[i];
64+
result += rem[i] * inv(pp, num[i]) * pp;
65+
}
66+
67+
return result % prod;
68+
}
69+
70+
// Main method
71+
72+
int main(void)
73+
{
74+
int num[] = {3, 4, 5};
75+
int rem[] = {2, 3, 1};
76+
int k = sizeof(num)/sizeof(num[0]);
77+
cout << "x is " << findMinX(num, rem, k);
78+
return 0;
79+
}
80+
81+
Output:
82+
83+
x is 11
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Iterative C++ program to find modular inverse using extended Euclid algorithm.
2+
// Returns modulo inverse of a with respect to m using extended Euclid Algorithm.
3+
//Time Complexity of this method is O(Log m).
4+
// Assumption: a and m are coprimes, i.e., gcd(a, m) = 1
5+
6+
#include <stdio.h>
7+
int modInverse(int a, int m)
8+
{
9+
int m0 = m, t, q;
10+
int x0 = 0, x1 = 1;
11+
12+
if (m == 1)
13+
return 0;
14+
15+
while (a > 1)
16+
{
17+
// q is quotient
18+
q = a / m;
19+
20+
t = m;
21+
22+
// m is remainder
23+
m = a % m, a = t;
24+
25+
t = x0;
26+
27+
x0 = x1 - q * x0;
28+
29+
x1 = t;
30+
}
31+
32+
// Make x1 positive
33+
if (x1 < 0)
34+
x1 += m0;
35+
36+
return x1;
37+
}
38+
39+
// Main method
40+
int main()
41+
{
42+
int a = 3, m = 11;
43+
44+
printf("Modular multiplicative inverse is %d\n",
45+
modInverse(a, m));
46+
return 0;
47+
}
48+
49+
Output:
50+
Modular multiplicative inverse is 4.

0 commit comments

Comments
 (0)