Knight Moves
March 8, 2013
[ Today’s exercise comes from “Learn You a Haskell for Great Good” written by Miran Lipovača; the solution was written by Kyle Ilantzis. Guest authors are always welcome; if you are interested, contact me at the email address on the menu bar. By the way, that’s a fine place to start if you want to learn about Haskell. ]
This exercise comes from “Learn You a Haskell for Great Good!” by Miran Lipovača. Lipovača demonstrates a solution to find out if a single knight piece on a chessboard can reach a position in three moves. As an exercise he suggests that we try to find out if that knight can reach a position on the board in n moves and if so, what are the moves that the knight should make.
Your task is to write a function that given a starting position, ending position, and n number of moves to take, returns a list of all possible paths that that knight piece could take to reach the goal. If some input has no solution then simply return an empty list. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.
[…] today’s Programming Praxis exercise, our goal is to list all the potential ways a knight on a chess board […]
My Haskell solution (see http://bonsaicode.wordpress.com/2013/03/08/programming-praxis-knight-moves/ for a version with comments):
My attempt in Python:
Also, just thought I’d point out that you said there are 109 ways to move from (1,1) to (8,8) but there are actually only 108. (Your output has 109 lines but the top line is just the description!)
Python, too
Here’s my version in Racket:
Full writeup (including the source for
knight-neighbors
andin-bounds?
, although they’re pretty much exactly what you’d expect) on my blog: Knight movesMy solution in Common Lisp closely follows the Racket solution, so I will not repeat it. But in the Racket and other codes I don’t see tests to see whether the path has either reached the target position in fewer than the required number of moves, or whether the path has revisited a previously visited position.
This does not make a difference for n=6. But for n=8 if we allow for revisiting, I get 5124 paths, and if we prohibit them, we get 1896 paths.
A related problem that I did not have the CPU, machine resources or patience to analyze is to obtain the distribution of the number of paths as function of number of moves. If we prohibit the path from revisiting positions after increasing (6: 108, 8: 1896, 10: 40252, 12: 731642, …) the number of paths for n-max large should eventually decrease and go to zero after 64 moves (The wikipedia page http://en.wikipedia.org/wiki/Knight%27s_tour shows a tour that covers the 8×8 board).