A Knight’s Watch
Recently I came across this interesting problem through Toptal (on Codility) which kept me thinking hard for a few days. Finally, I now have a solution to this problem and would like to share it here.
Basically, the problem deals with a knight piece on an infinite chess board. Assuming the knight is positioned at (0,0) you are asked to calculate and print the shortest path that the knight can take to get to the target location.
So what is given here?
- The Knight’s movement is well defined i.e. it can only move in a ‘L’ shape.
- The Knight has option to move to any of the 8 different locations from it’s current position.
Now with these key points in mind, we can calculate which move will take the Knight closest to the given target i.e. move the knight in the direction of shortest distance.
For example: Suppose our target is located at (6,7).
Now, from (0,0) the Knight can move to following points: (1,2), (2,1), (-1,2), (-2,1), (-1,-2), (-2,-1), (1,-2) and (2,-1).
But out of these 8 points, the closest one is (1,2). So we move the knight to this position in first move. For each step we can use the same logic to move the Knight.
Hence, the Knight moves to (1,2) in first step, (3,3) in second, (4,5) in third and (6,6) in fourth move.
However, once the Knight reaches a proximity distance of 1 unit, we will have to keep in mind a separate logic to hit the target.
This is because if we stick to our logic of moving the knight towards the shortest distance in all places, what will happen is once the knight reaches a close proximity, the Knight will start going round and round the target but never actually hit the target.
From (6,6), the Knight could jump to (7,8). From (7,8) it could jump to (5,7) and to (7,5) and all but never actually jump to (6,7).
So, we have to create a separate rule for this scenario for our Knight.
Close Proximity Rule:
There are again 8 different close proximity points from the target location’s view point : (7,7), (7,8), (6,8), (5,8), (5,7), (5,6), (6,6) and (7,6).
These eight points can be categorized into 2 types. Either they lie on the axes or they lie on the diagonals from the given target.
Points on Axes: (7,7), (6,8), (5,7) and (6,6)
Points on Diagonals: (7,8), (5,8), (5,6) and (7,6)
Based on these two types, the Knight can hit the target in either 2 or 3 moves.
If the Knight was at a point on the diagonal say (5,6), from there it can jump (7,5) and then to (6,7) in 2 two moves. All diagonal points can access the target in the center in two steps.
Similarly, all points on the x-y axes can hit the target in 3 steps. For example, if the Knight was at (6,6), it can jump to points (8,7), then to (7,9) and finally t (6,7).
Now with this much knowledge we can create a program that can calculate the shortest path that our Knight has to take to hit any target on an infinite chess board!
I have created a console application in C# to calculate the shortest path for the Knight to reach any stated target point with the above mentioned logic.
The application/project is available in git hub @ https://github.com/psovit/knightswatch
Please feel free to like, share and comment.