Chinese Remainder Theorem in Python (original) (raw)
Last Updated : 23 Jul, 2025
Consider two arrays ****"num[0..k-1]"** and "rem[0..k-1]", where every pair of numbers in num is coprime (i.e., the greatest common divisor (gcd) of every pair is 1). The goal is to find the minimum positive number "**x" such that:
x % num[0] = rem[0]
x % num[1] = rem[1]
.....
x % num[k-1] = rem[k-1]
In simpler terms, given "**k" numbers that are pairwise coprime and their corresponding remainders when an unknown number "**x" is divided by them, we aim to determine the smallest possible value of "**x" that satisfies these congruences.
**Examples:
**Input:
num[] = {3, 4, 5}
rem[] = {2, 3, 1}
**Output: 11
**Explanation: 11 is the smallest number such that:
(1) When we divide it by 3, we get remainder 2.
(2) When we divide it by 4, we get remainder 3.
(3) When we divide it by 5, we get remainder 1.**Input:
**num[] = {2, 3, 7}
**rem[] = {1, 2, 5}
**Output: 17
**Explanation: 17 is the smallest number such that:
(1) When we divide it by 2, we get remainder 1.
(2) When we divide it by 3, we get remainder 2.
(3) When we divide it by 7, we get remainder 5.
Chinese Remainder Theorem:
The Chinese Remainder Theorem states that for positive integers num[0], num[1], …, num[k-1] that are pairwise coprime, and any given sequence of integers **rem[0], rem[1], …, rem[k-1], there exists an integer **x that solves the system of simultaneous congruences as described earlier.
Chinese Remainder Theorem in Python Using Naive Approach:
Fetching the mystery number **x is fairly easy if we start with **1 and keep on seeing if numbers being divided by the elements in **num[] equals the corresponding remainders in **rem[]. Upon locating a variable like **x, the algorithm stops, and the solution is given. Yet, it can lead to inefficiency in cases with higher than average **num[].
**Steps-by-step approach for Chinese Remainder Theorem in Python:
- Initialize **x to 1 as the starting point for the search.
- Iterate through each **congruence and check if **xsatisfies the congruence by checking if**x **mod nums[ j**]=rems[ j**].
- If _**x_satisfies all **congruences, then we have found the solution _**x_and **return it.
- If _**x_does not satisfy all congruences, increment _**x_by 1 and **repeat the process.
Below is the implementation of the above approach:
Python `
def find_min_x(nums, rems):
Initialize result
x = 1
while True:
# Check if remainder of x % nums[j] is rem[j] for all j from 0 to k-1
for j in range(len(nums)):
if x % nums[j] != rems[j]:
break
# If all remainders matched, we found x
if j == len(nums) - 1:
return x
# Else, try the next number
x += 1
return xExample Usage
nums = [3, 4, 5] rems = [2, 3, 1] print(find_min_x(nums, rems))
`
**Time Complexity: O(M), where **M is the product of all elements in the **nums array.
**Auxiliary Space: O(1)
Chinese Remainder Theorem in Python Using Extended Euclidean Algorithm:
The Extended Euclidean Algorithm is used to find the greatest common divisor (GCD) of two integers **a and **b, as well as the coefficients_x_ and **y such that **ax****+ by=gcd( a, b)
**Steps-by-step algorithm:
- Compute the product of all numbers in the **num[] array. Let's call this product **prod.
- For each pair of **num[i] and **rem[i], compute the product of all numbers in num[] except num[i], denoted as **prod_i.
- Use the Extended Euclidean Algorithm to find the modular inverse of prod_i modulo num[i]. Let's call this inverse inv_i.
- Calculate the solution **x using the formula:

Formula
Below is the implementation of the above approach:
Python `
def gcd_extended(a, b): if a == 0: return b, 0, 1 gcd, x1, y1 = gcd_extended(b % a, a) x = y1 - (b // a) * x1 y = x1 return gcd, x, y
def find_min_x(num, rem): prod = 1 for n in num: prod *= n
result = 0
for i in range(len(num)):
prod_i = prod // num[i]
_, inv_i, _ = gcd_extended(prod_i, num[i])
result += rem[i] * prod_i * inv_i
return result % prodExample Usage
num1 = [5, 7] rem1 = [1, 3] print("x is", find_min_x(num1, rem1))
num2 = [3, 4, 5] rem2 = [2, 3, 1] print("x is", find_min_x(num2, rem2))
`
Output
('x is', 31) ('x is', 11)
**Time Complexity : O(k log(prod)) where k is the number of elements in the array and prod is the product of the elements in the array.
**Auxiliary Space : O(1)