I came across a programming challenge that has been tearing me up for those. It's named "dice straight".
Basically, you're given m x 6 matrices (the column length is always 6 but the rows vary), and you're to find the length of the longest string of adjacent integers that can be formed picking one integer from each row. That means, you can't take 2 integers from one row and you can't leave a row out.
For example, one of the matrix is
[4 8 15 16 23 42]
[8 6 7 5 30 9 ]
[1 2 3 4 55 6 ]
[2 10 18 36 54 86]
The longest straight can be formed taking 2 from row4, 3 from row3, 4 from row1 and 5 from row 2. That's 2,3,4,5. So it returns 4, the length.
The code I have now works for the above matrix and moderately sized matrices, but when it gets to 100 x 6 matrices, it runs forever. I'm using a combination of back track algorithm and depth first. First, I combine the rows into one array and sort them, then, using a stack, I pick numbers on the condition that it's adjacent to the stack top and it's not on the same row as any integer in the stack, and when it reaches a dead-end, I dequeue until I get to last working solution.
static int maxLength(Face[] faces, int d){
faces = quickSort(faces, 0, faces.length - 1);
for (int i = 0; i < faces.length - 1; i++) {
if(faces[i].side == faces[i+1].side && faces[i].dice > faces[i+1].dice){
Face temp = faces[i];
faces[i] = faces[i+1];
faces[i+1] = temp;
}
}
//System.out.println(faces.length);
for (int i = 0; i < faces.length; i++) {
//System.out.print(faces[i]+" ");
}
int maxLength = 1;
for (int i = 0; i < faces.length; i++) {
Stack<Face> tree = new Stack<>();
Stack<Integer> dices = new Stack<>();
Stack<Integer> sides = new Stack<>();
int length = 1;
tree.add(faces[i]);
dices.add(faces[i].dice);
sides.add(faces[i].side);
int pos = i;
//System.out.print(faces[pos].side + ", ");
while(!tree.isEmpty() && pos < faces.length - 1){
pos++;
//System.out.println(faces[pos] + "}"+faces[pos + 1]);
if(faces[pos].side - faces[pos - 1].side == 2){
for(Face ig : tree){
//System.out.print(ig+" ");
}
//System.out.println("/"+faces[pos]+"/"+length);
i = pos;
break;
}
faces[pos].visited = true;
//System.out.print(tree.peek().side + " ");
if(!dices.contains(faces[pos].dice) && faces[pos].side - tree.peek().side == 1){
tree.push(faces[pos]);
dices.push(faces[pos].dice);
//System.out.print(faces[pos].side + " ");
length++;
maxLength = Math.max(length, maxLength);
if(maxLength == d){
i = 5000000;
//System.out.println("beeeeeee");
//System.out.println(tree.size());
for(Face ig : tree){
//System.out.print(ig+" ");
}
break;
}
}else if(faces[pos].side - tree.peek().side == 2){
Face a = tree.peek();
Face x = tree.pop();
//System.out.println(tree.peek()+"|"+x+"|"+length+"|"+faces[pos]);
pos = Arrays.asList(faces).indexOf(x)+1;
dices.pop();
length--;
for(Face ig : tree){
//System.out.println(ig);
}
//System.out.println();
}else if(faces[pos].side - tree.peek().side > 2){
}
}
//System.out.println();
for(Face ig : tree){
//System.out.println(ig);
}
}
return maxLength;
}
"Face" is a class with 2 fields. 'Side', which represents the integer in a row i and dice, which represents 'i'. Face[] is an array of all the elements in the matrix, sorted in ascending order of 'side'. So Face[] for the above matrix would be
1(2) 2(2) 2(3) 3(2) 4(0) 4(2) 5(1) 6(1) 6(2) 7(1) 8(0) 8(1) 9(1) 10(3) 15(0) 16(0) 18(3) 23(0) 30(1) 36(3) 42(0) 54(3) 55(2) 86(3) in x(y) format where x is side and y is dice.
I found the challenge in the link below. If you don't understand my question, please check this. https://code.google.com/codejam/contest/6314486/dashboard#s=p0&a=0
I'll very much appreciate it if anyone points me in the right direction. Thank you.