This article discusses how to solve linear congruence equations.
Basic Concepts
Let be integers and an unknown. An equation of the form
is called a linear congruence equation (linear congruence equation).
To solve a linear congruence equation, we need to find all solutions for in the interval . Of course, adding or subtracting any multiple of from them still gives a solution to the equation. In the sense of modulo , these are all the solutions to the equation.
This article introduces two approaches to solving linear congruence equations, using inverses and Diophantine equations respectively. In general, solving both inverses and Diophantine equations requires the extended Euclidean algorithm, so these two approaches are actually consistent.
Solving with an Inverse
First, consider the case where and are coprime, that is, . In this case, we can calculate the inverse of and multiply both sides of the equation by , obtaining the unique solution:
Next, consider the case where and are not coprime, that is, . In this case, the original equation may not have a solution. For example, has no solution. Therefore, two cases need to be considered:
-
When does not divide , the equation has no solution. For any , the left-hand side is a multiple of , but the right-hand side is not a multiple of . Therefore, they cannot differ by a multiple of , because any multiple of must also be a multiple of . Thus, the equation has no solution.
-
When divides , divide all three parameters in the equation by to obtain a new equation:
Here, , which means that and are coprime. This case was solved above, so a solution to the equation can be obtained by finding an inverse.
Clearly, is also a solution to the original equation. However, it is not the only solution to the original equation. Since the complete set of solutions to the transformed equation is
Among these solutions, those in the interval are exactly all the solutions to the original equation in the interval :
Summarizing these two cases, the number of solutions to a linear congruence equation is or .
Solving with a Diophantine Equation
A linear congruence equation is equivalent to the binary linear Diophantine equation in :
Using the discussion on the referenced page, the equation has a solution if and only if , and one general solution to the equation is
where is their greatest common divisor and is any integer.
Consequently, the general solution to the linear congruence equation is
Taking modulo gives the smallest (nonnegative) integer solution to the congruence equation, namely the above.
Reference Implementation
The reference implementations in this section obtain the smallest nonnegative integer solution to the congruence equation. If no solution exists, they output .
Reference Implementation
C++
// Extended Euclidean Algorithm.
// Finds integers x, y such that a*x + b*y = gcd(a, b),
// and returns gcd(a, b).
int ex_gcd(int a, int b, int& x, int& y) {
if (!b) {
x = 1;
y = 0;
return a;
} else {
int d = ex_gcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
}
// Solves the linear congruence equation:
// a * x ≡ b (mod n), where n > 0.
// Returns the smallest non-negative solution x,
// or -1 if there is no solution.
int solve_linear_congruence_equation(int a, int b, int n) {
int x, y;
int d = ex_gcd(a, n, x, y);
if (b % d) return -1;
n /= d;
return ((long long)x * (b / d) % n + n) % n;
}
Python
def ex_gcd(a, b):
"""
Extended Euclidean Algorithm.
Finds integers x, y such that a*x + b*y = gcd(a, b),
and returns (gcd, x, y).
"""
if b == 0:
return a, 1, 0
d, x1, y1 = ex_gcd(b, a % b)
x = y1
y = x1 - (a // b) * y1
return d, x, y
def solve_linear_congruence_equation(a, b, n):
"""
Solves the linear congruence equation:
a * x ≡ b (mod n), where n > 0.
Returns the smallest non-negative solution x,
or -1 if there is no solution.
"""
d, x, y = ex_gcd(a, n)
if b % d != 0:
return -1
n //= d
return (x * (b // d) % n + n) % n
Exercises
This page is mainly translated from the blog post Модульное линейное уравнение первого порядка and its English translation Linear Congruence Equation. The Russian version is licensed under Public Domain + Leave a Link; the English version is licensed under CC-BY-SA 4.0. The content has been modified.