patternjavaModerate
Given sum and product, find the two variables
Viewed 0 times
sumtheproducttwovariablesfindandgiven
Problem
Basically, find x and y given the product = xy and sum = x + y. I would like review on optimization, clean code, and complexity. It looks like O(1), but the
```
/**
* x will always be less than or equal to y.
*/
final class Variables {
private final int x;
private final int y;
Variables(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
@Override public String toString() {
return " x = " + x + " y = " + y;
}
}
/**
* @author SERVICE-NOW\ameya.patil
*/
public final class SimultaneousEquations {
private SimultaneousEquations () {}
/**
* Provided we dont have positive product and -ve sum,
* return value would be the smallest posive integer of the variable.
*
* @param product : product of x and y
* @param sum : sum of x and y
* @return : smallest positive integer of x and y.
*/
private static int getX(int product, int sum) {
assert product != 0;
assert product 0 && sum > 0);
int x = 1;
while (xx != (sum x - product)) {
x++;
}
return x;
}
/**
* Given a product and a sum, return two variables.
*
* @param sum : sum of two variables
* @param product : product of two variables
*/
public static Variables getVariables(int product, int sum) {
if (product == 0) {
if (sum < 0) {
return new Variables(sum, 0);
} else {
return new Variables(0, sum);
}
}
if (product < 0) {
int x = getX(product, sum);
return new Variables(product/x, x);
}
if (sum < 0) {
int x = -getX(product, -sum);
return new Variables(product/x, x);
}
int x = getX(produc
while loop makes me wonder if it's something different.```
/**
* x will always be less than or equal to y.
*/
final class Variables {
private final int x;
private final int y;
Variables(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
@Override public String toString() {
return " x = " + x + " y = " + y;
}
}
/**
* @author SERVICE-NOW\ameya.patil
*/
public final class SimultaneousEquations {
private SimultaneousEquations () {}
/**
* Provided we dont have positive product and -ve sum,
* return value would be the smallest posive integer of the variable.
*
* @param product : product of x and y
* @param sum : sum of x and y
* @return : smallest positive integer of x and y.
*/
private static int getX(int product, int sum) {
assert product != 0;
assert product 0 && sum > 0);
int x = 1;
while (xx != (sum x - product)) {
x++;
}
return x;
}
/**
* Given a product and a sum, return two variables.
*
* @param sum : sum of two variables
* @param product : product of two variables
*/
public static Variables getVariables(int product, int sum) {
if (product == 0) {
if (sum < 0) {
return new Variables(sum, 0);
} else {
return new Variables(0, sum);
}
}
if (product < 0) {
int x = getX(product, sum);
return new Variables(product/x, x);
}
if (sum < 0) {
int x = -getX(product, -sum);
return new Variables(product/x, x);
}
int x = getX(produc
Solution
Before we start guessing, lets solve the equations properly. We can substitute the equations so that we get
The equation can be solved by
Restricting yourself to integers only isn't valid, and will miss some solutions. Consider
Note that as this equation can be solved arithmetically, there is no need for guessing via loops.
Because you resort to guessing, your code contains various bugs, e.g. it will fail to handle parameters with no solution like
When unit-testing your code, you should be using a proper test harness instead of some test cases in a
product = x · (sum - x) = -x² + sum·x ⇔ 0 = x² - sum·x + product, with y = sum - x.The equation can be solved by
x = sum/2 ± √(sum²/4 - product) (see Reduced Quadratic Equation). Note that we get zero, one or two distinct solutions. For example the special case of product = 0 leads to x = sum/2 ± sum/2 ⇒ {x = 0, x = sum}. It is up to you if you pick a specific solution or output both. We have no solutions in ℝ when the expression inside the square root is negative. However, there would still be complex solutions.Restricting yourself to integers only isn't valid, and will miss some solutions. Consider
product = 1, sum = 4. This is solved by x=3.73205, y=0.267949.Note that as this equation can be solved arithmetically, there is no need for guessing via loops.
Because you resort to guessing, your code contains various bugs, e.g. it will fail to handle parameters with no solution like
sum = 4, product = 5. Instead, you will go into an unterminated loop.When unit-testing your code, you should be using a proper test harness instead of some test cases in a
main. You might like JUnit. If you want to thoroughly test a method, do not only test a few simple cases:- Explicitly test failure cases, e.g. parameters with no solution.
- Test especially large inputs to see if you correctly guarded against overflows (you didn't).
- Test random input (and record the seed!). It is easy to verify the correctness of the solution. This fuzzy testing may hit cases you didn't consider.
- Cover inputs around zero especially well, e.g. vary each parameter from
-2to2by0.5-increments (after verifying manually that each parameter combination actually has a solution). Although this wouldn't hit another bug in your code, the combination0, 0is suspiciously absent. The combination1, 0would have exposed the bug that you don't handle inputs without solutions.
Context
StackExchange Code Review Q#35744, answer score: 13
Revisions (0)
No revisions yet.