I need to find linear conflicts of 8 puzzle state, state is represented by int[9]
, goal state is {1,2,3,4,5,6,7,8,0}. A linear conflict would be if in a line two tiles that are supposed to be in that line are reversed.
For example, in goal state, the first row is 1,2,3 if in the state the first row is 2,1,3 then that is one linear conflict made by tiles 2 and 1.
My code works, but is way too long and awkward. Here it is:
public static int linearConflicts(int[] state) {
ArrayList<Integer> row1 = new ArrayList<Integer>();
ArrayList<Integer> row2 = new ArrayList<Integer>();
ArrayList<Integer> row3 = new ArrayList<Integer>();
ArrayList<Integer> column1 = new ArrayList<Integer>();
ArrayList<Integer> column2 = new ArrayList<Integer>();
ArrayList<Integer> column3 = new ArrayList<Integer>();
int[] columnMarkers = new int[] { 0, 3, 6, 1, 4, 7, 2, 5, 8 };
for (int i = 0; i < 9; i++) {
if (i < 3) {
row1.add(state[i]);
column1.add(state[columnMarkers[i]]);
} else if (i < 6) {
row2.add(state[i]);
column2.add(state[columnMarkers[i]]);
} else {
row3.add(state[i]);
column3.add(state[columnMarkers[i]]);
}
}
return row1Conflicts(row1) + row2Conflicts(row2) + row3Conflicts(row3)
+ column1Conflicts(column1) + column2Conflicts(column2)
+ column3Conflicts(column3);
}
public static int row1Conflicts(ArrayList<Integer> rowState) {
int conflicts = 0;
if (rowState.contains(1)) {
if ((rowState.contains(2))
&& rowState.indexOf(1) > rowState.indexOf(2)) {
conflicts++;
}
if ((rowState.contains(3))
&& rowState.indexOf(1) > rowState.indexOf(3)) {
conflicts++;
}
}
if (rowState.contains(2) && rowState.contains(3)
&& rowState.indexOf(2) > rowState.indexOf(3))
conflicts++;
return conflicts;
}
public static int row2Conflicts(ArrayList<Integer> rowState) {
int conflicts = 0;
if (rowState.contains(4)) {
if ((rowState.contains(5))
&& rowState.indexOf(4) > rowState.indexOf(5)) {
conflicts++;
}
if ((rowState.contains(6))
&& rowState.indexOf(4) > rowState.indexOf(6)) {
conflicts++;
}
}
if (rowState.contains(5) && rowState.contains(6)
&& rowState.indexOf(5) > rowState.indexOf(6))
conflicts++;
return conflicts;
}
public static int row3Conflicts(ArrayList<Integer> rowState) {
int conflicts = 0;
if (rowState.contains(7) && rowState.contains(8)
&& rowState.indexOf(7) > rowState.indexOf(8))
conflicts++;
return conflicts;
}
public static int column1Conflicts(ArrayList<Integer> columnState) {
int conflicts = 0;
if (columnState.contains(1)) {
if ((columnState.contains(4))
&& columnState.indexOf(1) > columnState.indexOf(4)) {
conflicts++;
}
if ((columnState.contains(7))
&& columnState.indexOf(1) > columnState.indexOf(7)) {
conflicts++;
}
}
if (columnState.contains(4) && columnState.contains(7)
&& columnState.indexOf(4) > columnState.indexOf(7))
conflicts++;
return conflicts;
}
public static int column2Conflicts(ArrayList<Integer> columnState) {
int conflicts = 0;
if (columnState.contains(2)) {
if ((columnState.contains(5))
&& columnState.indexOf(2) > columnState.indexOf(5)) {
conflicts++;
}
if ((columnState.contains(8))
&& columnState.indexOf(2) > columnState.indexOf(8)) {
conflicts++;
}
}
if (columnState.contains(5) && columnState.contains(8)
&& columnState.indexOf(5) > columnState.indexOf(8))
conflicts++;
return conflicts;
}
public static int column3Conflicts(ArrayList<Integer> columnState) {
int conflicts = 0;
if (columnState.contains(3) && columnState.contains(6)
&& columnState.indexOf(3) > columnState.indexOf(6))
conflicts++;
return conflicts;
}
Does anyone know how to do it shorter and less clumsy? If I keep doing methods like this, my code will be very hard to read.