patternjavaMinor
Solve 6 simultaneous equations for 8 variables puzzle with Java
Viewed 0 times
equationswithjavasimultaneousforsolvevariablespuzzle
Problem
I came across this mathematical puzzle, where one really cool answer was a python script to brute force answers.
Here's my take, which is essentially a translation of that to Java:
```
public class TerribleMath {
public static void main(String[] args) {
findAndPrintSolutions(1, 20);
}
private static void findAndPrintSolutions(int from, int to) {
for (int a = from; a < to; a++) {
for (int b = from; b < to; b++) {
for (int c = from; c < to; c++) {
for (int d = from; d < to; d++) {
for (int e = from; e < to; e++) {
for (int f = from; f < to; f++) {
for (int g = from; g < to; g++) {
for (int h = from; h < to; h++) {
if (isSolution(a, b, c, d, e, f, g, h))
printSolution(new int[] { a, b, c, d, e, f, g, h });
}
}
}
}
}
}
}
}
}
private static boolean isSolution(int a, int b, int c, int d, int e, int f, int g, int h) {
if (a + b - 9 != 4)
return false;
if ((c - d) * e != 4)
return false;
if (f + g - h != 4)
return false;
if ((a + c) / f != 4)
return false;
if ((b - d) * g != 4)
return false;
if (9 - e - h != 4)
return false;
return true;
}
private static void printSolution(int[] variables) {
StringBuilder output = new StringBuilder();
for (int variable : variables) {
output.append(variable + ", ");
}
output.deleteCharAt(output.length() - 1);
output.deleteCharAt(output.length() - 1);
System.out.println(output.toString());
Here's my take, which is essentially a translation of that to Java:
```
public class TerribleMath {
public static void main(String[] args) {
findAndPrintSolutions(1, 20);
}
private static void findAndPrintSolutions(int from, int to) {
for (int a = from; a < to; a++) {
for (int b = from; b < to; b++) {
for (int c = from; c < to; c++) {
for (int d = from; d < to; d++) {
for (int e = from; e < to; e++) {
for (int f = from; f < to; f++) {
for (int g = from; g < to; g++) {
for (int h = from; h < to; h++) {
if (isSolution(a, b, c, d, e, f, g, h))
printSolution(new int[] { a, b, c, d, e, f, g, h });
}
}
}
}
}
}
}
}
}
private static boolean isSolution(int a, int b, int c, int d, int e, int f, int g, int h) {
if (a + b - 9 != 4)
return false;
if ((c - d) * e != 4)
return false;
if (f + g - h != 4)
return false;
if ((a + c) / f != 4)
return false;
if ((b - d) * g != 4)
return false;
if (9 - e - h != 4)
return false;
return true;
}
private static void printSolution(int[] variables) {
StringBuilder output = new StringBuilder();
for (int variable : variables) {
output.append(variable + ", ");
}
output.deleteCharAt(output.length() - 1);
output.deleteCharAt(output.length() - 1);
System.out.println(output.toString());
Solution
If willing to mix the solution checking logic into the candidate generation logic, we can do better if we drop the requirement that we brute force the entire answer.
This would drop us from 25,600,000,000 iterations of the innermost loop to 8000 with a modest increase in complexity per iteration. This works because the equations in the solution checker tell us constraints that we can use to determine some of the variables if we have others (comments in the code with more specific explanations). With sufficient algebra you might eliminate one of the remaining three loops as well. Note that we have an additional equation that we are not using (
Added logic to verify that the calculated variables are within the
private static void findAndPrintSolutions(int from, int to) {
for (int a = from; a b || b > to) {
continue;
}
for (int c = from; c f || f > to) {
continue;
}
for (int d = from; d e || e > to) {
continue;
}
// if (b - d) * g == 4
int g = 4 / (b - d);
if (from > g || g > to) {
continue;
}
// if 9 - e - h == 4
int h = 5 - e;
if (from > h || h > to) {
continue;
}
if (isSolution(a, b, c, d, e, f, g, h)) {
printSolution(new int[] { a, b, c, d, e, f, g, h });
}
}
}
}
}This would drop us from 25,600,000,000 iterations of the innermost loop to 8000 with a modest increase in complexity per iteration. This works because the equations in the solution checker tell us constraints that we can use to determine some of the variables if we have others (comments in the code with more specific explanations). With sufficient algebra you might eliminate one of the remaining three loops as well. Note that we have an additional equation that we are not using (
f + g - h == 4). Added logic to verify that the calculated variables are within the
from/to range. This doesn't seem to have been necessary for this particular problem, but that seems likely to have been just luck. I think that you could probably demonstrate that by setting from to 1 and to to 6.Code Snippets
private static void findAndPrintSolutions(int from, int to) {
for (int a = from; a < to; a++) {
// if a + b - 9 == 4, then
int b = 13 - a;
if (from > b || b > to) {
continue;
}
for (int c = from; c < to; c++) {
// if (a + c) / f == 4
int f = (a + c) / 4;
if (from > f || f > to) {
continue;
}
for (int d = from; d < to; d++) {
if (c == d || b == d) {
// these cause divide by zero errors later, so skip them
continue;
}
// if (c - d) * e == 4
int e = 4 / (c - d);
if (from > e || e > to) {
continue;
}
// if (b - d) * g == 4
int g = 4 / (b - d);
if (from > g || g > to) {
continue;
}
// if 9 - e - h == 4
int h = 5 - e;
if (from > h || h > to) {
continue;
}
if (isSolution(a, b, c, d, e, f, g, h)) {
printSolution(new int[] { a, b, c, d, e, f, g, h });
}
}
}
}
}Context
StackExchange Code Review Q#126071, answer score: 7
Revisions (0)
No revisions yet.