import java.util.LinkedList;
import java.util.Queue;
/**
* Find the least number of hops between source and destination
* @author PRATEEK
*/
class KnightShortestPath {
private static final int BLANK = -1;
private static int rowLen;
private static int colLen;
private int[][] board;
private static Queue<Coordinate> queue;
public static void main
(String[] args
) {
int[][] board =
{ { -1, -1, -1, -1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1, -1, -1, -1 } };
rowLen = board.length;
colLen = board[0].length;
int hops= path(board, 0, 0,rowLen -1 ,colLen -1 );
System.
out.
println(hops
+ " Moves"); }
/**
* BFS to find the minimum moves to reach the destination
* @return return number of hops if solution is availale else -1
*/
public static int path(int[][] board, int startRow, int startCol, int endRow, int endCol) {
queue = new LinkedList<Coordinate>();
queue.add(new Coordinate(startRow, startCol));
queue.add(null); //this acts a delimiter
board[startRow][startCol] = 0;
int hops=0;
while (!queue.isEmpty()) {
Coordinate popedItem = queue.poll();
if (popedItem == null) {
hops++;
queue.offer(null);
//System.out.println("======");
continue;
}
int r = popedItem.row;
int c = popedItem.col;
board[r][c] = hops;
//System.out.println(hops + " " + r + " " + c);
if(r==endRow && c==endCol)
{
printSol(board);
return hops;
}
Coordinate[] points = validCoordinates(board, r, c);
for (Coordinate o : points) {
if (o != null)
queue.add(o);
}
}
return -1;
}
private static boolean isValid(int[][] board, int row, int col) {
if (row >= 0 && row < colLen && col >= 0 && col < rowLen
&& board[row][col] == BLANK)
return true;
return false;
}
public static Coordinate[] validCoordinates(int[][] board, int row, int col) {
Coordinate[] points = new Coordinate[8];
if (isValid(board, row + 2, col + 1))
points[0] = new Coordinate(row + 2, col + 1);
if (isValid(board, row + 1, col + 2))
points[1] = new Coordinate(row + 1, col + 2);
if (isValid(board, row - 1, col + 2))
points[2] = new Coordinate(row - 1, col + 2);
if (isValid(board, row - 2, col + 1))
points[3] = new Coordinate(row - 2, col + 1);
if (isValid(board, row - 2, col - 1))
points[4] = new Coordinate(row - 2, col - 1);
if (isValid(board, row - 1, col - 2))
points[5] = new Coordinate(row - 1, col - 2);
if (isValid(board, row + 1, col - 2))
points[6] = new Coordinate(row + 1, col - 2);
if (isValid(board, row + 2, col - 1))
points[7] = new Coordinate(row + 2, col - 1);
return points;
}
private static void printSol(int[][] board) {
for(int i=0;i<colLen;i++)
{
for(int j=0;j<rowLen;j++)
{
System.
out.
print(board
[i
][j
]+ " "); }
}
}
}
class Coordinate implements Comparable<Coordinate> {
public int row;
public int col;
public int level;
public Coordinate() {
row = 0;
col = 0;
}
public Coordinate(int row, int col) {
this.row = row;
this.col = col;
this.level = level;
}
@Override
public int compareTo(Coordinate that) {
return this.row - that.row - this.col - that.col;
}
}
aW1wb3J0IGphdmEudXRpbC5MaW5rZWRMaXN0OwppbXBvcnQgamF2YS51dGlsLlF1ZXVlOwoKLyoqCiAqIEZpbmQgdGhlIGxlYXN0IG51bWJlciBvZiBob3BzIGJldHdlZW4gc291cmNlIGFuZCBkZXN0aW5hdGlvbgogKiBAYXV0aG9yIFBSQVRFRUsKICovCmNsYXNzIEtuaWdodFNob3J0ZXN0UGF0aCB7CgoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEJMQU5LID0gLTE7Cglwcml2YXRlIHN0YXRpYyBpbnQgcm93TGVuOwoJcHJpdmF0ZSBzdGF0aWMgaW50IGNvbExlbjsKCXByaXZhdGUgaW50W11bXSBib2FyZDsKCglwcml2YXRlIHN0YXRpYyBRdWV1ZTxDb29yZGluYXRlPiBxdWV1ZTsKCQoJcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgewoKCQlpbnRbXVtdIGJvYXJkID0gCgkJCSAgeyB7IC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSB9LAoJCQkJeyAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEgfSwKCQkJCXsgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xIH0sCgkJCQl7IC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSB9LAoKCQkJCXsgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xIH0sCgkJCQl7IC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSB9LAoJCQkJeyAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEgfSwKCQkJCXsgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsIC0xIH0gfTsKCgkJcm93TGVuID0gYm9hcmQubGVuZ3RoOwoJCWNvbExlbiA9IGJvYXJkWzBdLmxlbmd0aDsKCWludCBob3BzPQlwYXRoKGJvYXJkLCAwLCAwLHJvd0xlbiAtMSAsY29sTGVuIC0xICk7ClN5c3RlbS5vdXQucHJpbnRsbihob3BzICsgIiBNb3ZlcyIpOwoJfQoKCS8qKgoJICogQkZTIHRvIGZpbmQgdGhlIG1pbmltdW0gbW92ZXMgdG8gcmVhY2ggdGhlIGRlc3RpbmF0aW9uCgkgKiBAcmV0dXJuIHJldHVybiBudW1iZXIgb2YgaG9wcyBpZiBzb2x1dGlvbiBpcyBhdmFpbGFsZSBlbHNlIC0xCgkgKi8KCXB1YmxpYyBzdGF0aWMgaW50IHBhdGgoaW50W11bXSBib2FyZCwgaW50IHN0YXJ0Um93LCBpbnQgc3RhcnRDb2wsIGludCBlbmRSb3csIGludCBlbmRDb2wpIHsKCQlxdWV1ZSA9IG5ldyBMaW5rZWRMaXN0PENvb3JkaW5hdGU+KCk7CgkJcXVldWUuYWRkKG5ldyBDb29yZGluYXRlKHN0YXJ0Um93LCBzdGFydENvbCkpOwoJCXF1ZXVlLmFkZChudWxsKTsgIC8vdGhpcyBhY3RzIGEgZGVsaW1pdGVyCgkJYm9hcmRbc3RhcnRSb3ddW3N0YXJ0Q29sXSA9IDA7CgkJaW50IGhvcHM9MDsKCgkJd2hpbGUgKCFxdWV1ZS5pc0VtcHR5KCkpIHsKCQkJQ29vcmRpbmF0ZSBwb3BlZEl0ZW0gPSBxdWV1ZS5wb2xsKCk7CgoJCQlpZiAocG9wZWRJdGVtID09IG51bGwpIHsKCQkJCWhvcHMrKzsKCQkJCXF1ZXVlLm9mZmVyKG51bGwpOwoJCQkJLy9TeXN0ZW0ub3V0LnByaW50bG4oIj09PT09PSIpOwoJCQkJY29udGludWU7CgkJCX0gCgkJCQoJCQkJaW50IHIgPSBwb3BlZEl0ZW0ucm93OwoJCQkJaW50IGMgPSBwb3BlZEl0ZW0uY29sOwoKCQkJCWJvYXJkW3JdW2NdID0gaG9wczsKCQkJCQoJCQkJLy9TeXN0ZW0ub3V0LnByaW50bG4oaG9wcyArICIgIiArIHIgKyAiICIgKyBjKTsKCQkJCQoJCQkJaWYocj09ZW5kUm93ICYmIGM9PWVuZENvbCkKCQkJCXsKCQkJCQlwcmludFNvbChib2FyZCk7CgkJCQkJcmV0dXJuIGhvcHM7CgkJCQl9CgkJCQkJCgoJCQkJQ29vcmRpbmF0ZVtdIHBvaW50cyA9IHZhbGlkQ29vcmRpbmF0ZXMoYm9hcmQsIHIsIGMpOwoKCQkJCWZvciAoQ29vcmRpbmF0ZSBvIDogcG9pbnRzKSB7CgkJCQkJaWYgKG8gIT0gbnVsbCkKCQkJCQkJcXVldWUuYWRkKG8pOwoJCQkJfQoJCX0KCQlyZXR1cm4gLTE7Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc1ZhbGlkKGludFtdW10gYm9hcmQsIGludCByb3csIGludCBjb2wpIHsKCQlpZiAocm93ID49IDAgJiYgcm93IDwgY29sTGVuICYmIGNvbCA+PSAwICYmIGNvbCA8IHJvd0xlbgoJCQkJJiYgYm9hcmRbcm93XVtjb2xdID09IEJMQU5LKQoJCQlyZXR1cm4gdHJ1ZTsKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJcHVibGljIHN0YXRpYyBDb29yZGluYXRlW10gdmFsaWRDb29yZGluYXRlcyhpbnRbXVtdIGJvYXJkLCBpbnQgcm93LCBpbnQgY29sKSB7CgkJQ29vcmRpbmF0ZVtdIHBvaW50cyA9IG5ldyBDb29yZGluYXRlWzhdOwoKCQlpZiAoaXNWYWxpZChib2FyZCwgcm93ICsgMiwgY29sICsgMSkpCgkJCXBvaW50c1swXSA9IG5ldyBDb29yZGluYXRlKHJvdyArIDIsIGNvbCArIDEpOwoKCQlpZiAoaXNWYWxpZChib2FyZCwgcm93ICsgMSwgY29sICsgMikpCgkJCXBvaW50c1sxXSA9IG5ldyBDb29yZGluYXRlKHJvdyArIDEsIGNvbCArIDIpOwoKCQlpZiAoaXNWYWxpZChib2FyZCwgcm93IC0gMSwgY29sICsgMikpCgkJCXBvaW50c1syXSA9IG5ldyBDb29yZGluYXRlKHJvdyAtIDEsIGNvbCArIDIpOwoKCQlpZiAoaXNWYWxpZChib2FyZCwgcm93IC0gMiwgY29sICsgMSkpCgkJCXBvaW50c1szXSA9IG5ldyBDb29yZGluYXRlKHJvdyAtIDIsIGNvbCArIDEpOwoKCQlpZiAoaXNWYWxpZChib2FyZCwgcm93IC0gMiwgY29sIC0gMSkpCgkJCXBvaW50c1s0XSA9IG5ldyBDb29yZGluYXRlKHJvdyAtIDIsIGNvbCAtIDEpOwoKCQlpZiAoaXNWYWxpZChib2FyZCwgcm93IC0gMSwgY29sIC0gMikpCgkJCXBvaW50c1s1XSA9IG5ldyBDb29yZGluYXRlKHJvdyAtIDEsIGNvbCAtIDIpOwoKCQlpZiAoaXNWYWxpZChib2FyZCwgcm93ICsgMSwgY29sIC0gMikpCgkJCXBvaW50c1s2XSA9IG5ldyBDb29yZGluYXRlKHJvdyArIDEsIGNvbCAtIDIpOwoKCQlpZiAoaXNWYWxpZChib2FyZCwgcm93ICsgMiwgY29sIC0gMSkpCgkJCXBvaW50c1s3XSA9IG5ldyBDb29yZGluYXRlKHJvdyArIDIsIGNvbCAtIDEpOwoKCQlyZXR1cm4gcG9pbnRzOwoJfQoJCglwcml2YXRlIHN0YXRpYyB2b2lkIHByaW50U29sKGludFtdW10gYm9hcmQpIHsKCQlmb3IoaW50IGk9MDtpPGNvbExlbjtpKyspCgkJewoJCQlmb3IoaW50IGo9MDtqPHJvd0xlbjtqKyspCgkJCXsKCQkJCVN5c3RlbS5vdXQucHJpbnQoYm9hcmRbaV1bal0rICIgICAiKTsKCQkJfQoJCQlTeXN0ZW0ub3V0LnByaW50bG4oKTsKCQl9Cgl9Cn0KCmNsYXNzIENvb3JkaW5hdGUgaW1wbGVtZW50cyBDb21wYXJhYmxlPENvb3JkaW5hdGU+IHsKCglwdWJsaWMgaW50IHJvdzsKCXB1YmxpYyBpbnQgY29sOwoJcHVibGljIGludCBsZXZlbDsKCglwdWJsaWMgQ29vcmRpbmF0ZSgpIHsKCQlyb3cgPSAwOwoJCWNvbCA9IDA7Cgl9CgoJcHVibGljIENvb3JkaW5hdGUoaW50IHJvdywgaW50IGNvbCkgewoJCXRoaXMucm93ID0gcm93OwoJCXRoaXMuY29sID0gY29sOwoJCXRoaXMubGV2ZWwgPSBsZXZlbDsKCgl9CglAT3ZlcnJpZGUKCXB1YmxpYyBpbnQgY29tcGFyZVRvKENvb3JkaW5hdGUgdGhhdCkgewoJCXJldHVybiB0aGlzLnJvdyAtIHRoYXQucm93IC0gdGhpcy5jb2wgLSB0aGF0LmNvbDsKCX0KfQ==