Hi,

my solution is recursive and works only for small boards. The largest  
I solved was
9x9 (in 45 minutes):
   1  81  70   2  15  35   3  10  17
72  58  41  79  59  38  78  60  24
69  53  46  36  29   9  16  30   4
40  80  71  39  14  34  25  11  18
73  57  42  52  47  37  77  61  23
68  54  45  65  28   8  21  31   5
43  51  48  56  13  33  26  12  19
74  64  67  75  63  66  76  62  22
49  55  44  50  27   7  20  32   6

The main work is done in "each_neighbour" which iterates through all  
possible hops.
The board is a one-dimensional array, so it's easy to clone.

Regards,
Boris


### pnp.rb
class PenAndPaper
   def initialize(width)
     @width = width
   end

   def each_neighbour(pos)
     w = @width
     x = pos % w
     y = pos / w
     # north
     yield(pos - 3*w)     if y > 2
     # north east
     yield(pos - 2*w + 2) if y > 1 and x < w - 2
     # east
     yield(pos + 3)       if x < w - 3
     # south east
     yield(pos + 2*w + 2) if y < w - 2 and x < w - 2
     # south
     yield(pos + 3*w)     if y < w - 3
     # south west
     yield(pos + 2*w - 2) if y < w - 2 and x > 1
     # west
     yield(pos - 3)       if x > 2
     # north west
     yield(pos - 2*w - 2) if y > 1 and x > 1
   end

   def solve(pos=0)
     board = []
     board[pos] = 1
     @board = solve_board(board, pos, 2)
   end

   def solve_board(board, pos, ind)
     return board if ind > @width*@width
     each_neighbour(pos) do |n|
       next if board[n] # position already taken?
       f = board.dup
       f[n] = ind
       f2 = solve_board(f, n, ind + 1)
       return f2 if f2
     end
     nil # no more positions
   end

   def to_s
     s = ''
     (0...@width).each do |y|
       (0...@width).each do |x|
         s += "%3d " % @board[y*@width+x]
       end
       s += "\n"
     end
     s
   end
end



### test_pnp.rb
require 'test/unit'
require 'pnp'

class PenAndPaperTest < Test::Unit::TestCase
   def neighbours_of(pos)
     neighbours = []
     pnp = PenAndPaper.new(5)
     pnp.each_neighbour(pos) {|i| neighbours << i}
     neighbours
   end

   def test_neighbours
     assert_equal [ 3, 12, 15], neighbours_of(0)
     assert_equal [14, 17, 10], neighbours_of(2)
     assert_equal [18, 11,  0], neighbours_of(3)
     assert_equal [22, 11,  2], neighbours_of(14)
     assert_equal [ 2,  9,  5], neighbours_of(17)
     assert_equal [ 5, 12, 23], neighbours_of(20)
     assert_equal [ 9, 21, 12], neighbours_of(24)
   end

   def test_solve
     pnp = PenAndPaper.new(5)
     pnp.solve(0)
     assert_equal <<END, pnp.to_s
   1  22  12   2   7
19  25   5  20  10
13  16   8  23  15
   4  21  11   3   6
18  24  14  17   9
END
   end
end