Skip to content

Commit 7858187

Browse files
authored
Add Solver For Linear Diophantine Equations (TheAlgorithms#2744)
1 parent 447c5fa commit 7858187

File tree

1 file changed

+143
-0
lines changed

1 file changed

+143
-0
lines changed
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
package Maths;
2+
3+
import java.util.Objects;
4+
5+
public final class LinearDiophantineEquationsSolver {
6+
7+
public static void main(String[] args) {
8+
// 3x + 4y = 7
9+
final var toSolve = new Equation(3, 4, 7);
10+
System.out.println(findAnySolution(toSolve));
11+
}
12+
13+
public static Solution findAnySolution(final Equation equation) {
14+
if (equation.a() == 0 && equation.b() == 0 && equation.c() == 0) {
15+
return Solution.INFINITE_SOLUTIONS;
16+
}
17+
final var stub = new GcdSolutionWrapper(0, new Solution(0, 0));
18+
final var gcdSolution = gcd(equation.a(), equation.b(), stub);
19+
if (equation.c() % gcdSolution.getGcd() != 0) {
20+
return Solution.NO_SOLUTION;
21+
}
22+
final var toReturn = new Solution(0, 0);
23+
var xToSet = stub.getSolution().getX() * (equation.c() / stub.getGcd());
24+
var yToSet = stub.getSolution().getY() * (equation.c() / stub.getGcd());
25+
toReturn.setX(xToSet);
26+
toReturn.setY(yToSet);
27+
return toReturn;
28+
}
29+
30+
private static GcdSolutionWrapper gcd(final int a, final int b, final GcdSolutionWrapper previous) {
31+
if (b == 0) {
32+
return new GcdSolutionWrapper(a, new Solution(1, 0));
33+
}
34+
// stub wrapper becomes the `previous` of the next recursive call
35+
final var stubWrapper = new GcdSolutionWrapper(0, new Solution(0, 0));
36+
final var next = /* recursive call */ gcd(b, a % b, stubWrapper);
37+
previous.getSolution().setX(next.getSolution().getY());
38+
previous.getSolution().setY(next.getSolution().getX() - (a / b) * (next.getSolution().getY()));
39+
previous.setGcd(next.getGcd());
40+
return new GcdSolutionWrapper(next.getGcd(), previous.getSolution());
41+
}
42+
43+
public static final class Solution {
44+
public static final Solution NO_SOLUTION = new Solution(Integer.MAX_VALUE, Integer.MAX_VALUE);
45+
public static final Solution INFINITE_SOLUTIONS = new Solution(Integer.MIN_VALUE, Integer.MIN_VALUE);
46+
private int x;
47+
private int y;
48+
49+
public Solution(int x, int y) {
50+
this.x = x;
51+
this.y = y;
52+
}
53+
54+
public int getX() {
55+
return x;
56+
}
57+
58+
public int getY() {
59+
return y;
60+
}
61+
62+
public void setX(int x) {
63+
this.x = x;
64+
}
65+
66+
public void setY(int y) {
67+
this.y = y;
68+
}
69+
70+
@Override
71+
public boolean equals(Object obj) {
72+
if (obj == this) return true;
73+
if (obj == null || obj.getClass() != this.getClass()) return false;
74+
var that = (Solution) obj;
75+
return this.x == that.x &&
76+
this.y == that.y;
77+
}
78+
79+
@Override
80+
public int hashCode() {
81+
return Objects.hash(x, y);
82+
}
83+
84+
@Override
85+
public String toString() {
86+
return "Solution[" +
87+
"x=" + x + ", " +
88+
"y=" + y + ']';
89+
}
90+
91+
}
92+
93+
public record Equation(int a, int b, int c) {
94+
}
95+
96+
public static final class GcdSolutionWrapper {
97+
private int gcd;
98+
private Solution solution;
99+
100+
public GcdSolutionWrapper(int gcd, Solution solution) {
101+
this.gcd = gcd;
102+
this.solution = solution;
103+
}
104+
105+
@Override
106+
public boolean equals(Object obj) {
107+
if (obj == this) return true;
108+
if (obj == null || obj.getClass() != this.getClass()) return false;
109+
var that = (GcdSolutionWrapper) obj;
110+
return this.gcd == that.gcd &&
111+
Objects.equals(this.solution, that.solution);
112+
}
113+
114+
public int getGcd() {
115+
return gcd;
116+
}
117+
118+
public void setGcd(int gcd) {
119+
this.gcd = gcd;
120+
}
121+
122+
public Solution getSolution() {
123+
return solution;
124+
}
125+
126+
public void setSolution(Solution solution) {
127+
this.solution = solution;
128+
}
129+
130+
@Override
131+
public int hashCode() {
132+
return Objects.hash(gcd, solution);
133+
}
134+
135+
@Override
136+
public String toString() {
137+
return "GcdSolutionWrapper[" +
138+
"gcd=" + gcd + ", " +
139+
"solution=" + solution + ']';
140+
}
141+
142+
}
143+
}

0 commit comments

Comments
 (0)