A triangle needs a good foundation. Every row in the triangle is derived from the sum of the two values below it. However, there can be no repeated values, if a value shows up more than once the triangle crumbles. Find the base which minimises the value in the top of the triangle satisfying the condition of no duplicates.
Example:
20 8 12 [3] 5 7 1 2 [3] 4
Here 3 occurs twice, so the triangle is invalid
The base \$n\$ can be of any size \$n > 0\$ with
solve(1) = 1, solve(2) = [1, 2] = 3, solve(3) = [2, 1, 4] = 8
I would like suggestions on how I can improve:
- The code style or best practices, so the code is easy to read.
- The algorithm/constraints, I'm pretty sure that the loops can be made tighter, so not as many numbers have to be checked, but I can't figure out what the cut off is.
- Is there a better way to implement the base size without hard-coding extra nested loops, as this doesn't seem very scalable?
import java.util.*;
public class spaceship {
public static void main(String[] args) {
long start = System.nanoTime();
spaceship kling = new spaceship();
kling.solveAll();
System.out.println("Took: " + (System.nanoTime() - start) / 1000000 + "ms");
}
public void solveAll() {
int len = 6;
int bestFound = 400; //definitely big enough from previous tests
int res = bestFound;
int[] best = new int[len];
int[] x = new int[len];
int[] co = new int[] { 1, 1, 1, 1, 1, 1 };
for (int a = 1; co[0] * a < bestFound; a++) {
long beg = System.nanoTime();
for (int b = 1; co[1] * b < bestFound; b++) {
for (int c = 1; co[2] * c < bestFound; c++) {
for (int d = 1; co[3] * d < bestFound; d++) {
//for (int e = 1; co[4] * e < bestFound; e++) {
//for (int f = 1; co[5] * f < bestFound; f++) {
x = new int[] { a, b, c, d,/* e, f */};
res = solve(x);
if (res != -1 && res < bestFound) {
System.out.print(Arrays.toString(x));
System.out.println(":\t" + res);
bestFound = res;
best = x;
}
//}
//}
}
}
}
System.out.println((System.nanoTime() - beg) / 1000000 + "ms");
}
System.out.println("The best result possible is:");
System.out.println(bestFound);
System.out.println(Arrays.toString(best));
}
public int solve(int[] in) {
Set<Integer> data = new HashSet<>();
// check input for duplicates
// could be done in loops
for (int a : in) {
if (data.contains(a))
return -1;
data.add(a);
}
int size = in.length;
int[][] arr = new int[size][size];
arr[0] = in;
// first row is the input
// every row after is the sum of the two elements below it
// ie pascal's triangle with outermost values ignored
for (int i = 1; i < size; i++) {
for (int j = 0; j < size - i; j++) {
int a = arr[i - 1][j] + arr[i - 1][j + 1];
if (data.contains(a))
return -1;
data.add(a);
arr[i][j] = a;
}
}
// return final value, our result if no duplicates occur during the
// process
return arr[size - 1][0];
}
}