```This one will "possible" find solution for "cycle pattern".
It simply uses JC Warnsdorff (1823) rule,
so, it may not always find solution.

After my test, it does find cycle solutin for n = 5, 6, 15, 16, 22, 24, 25 ....
(Of couse, I could try add brute-forcing, but don't have time to play
with it now... )

class PenAndPaperGame2
MOVES = [[3,0], [-3,0], [0,3], [0,-3], [2,2], [2,-2], [-2,2], [-2,-2]]

def initialize(size)
@size = size
@board = Array.new(@size) { Array.new(@size) }
@found = false
end

def to_s
return "No soultion" unless @found
digits = (@size * @size).to_s.size
" #{'-' * (digits+2) * @size}\n|" +
(@board.map { |l| l.map{|e| " %#{digits}d " % e}.join }.join("|\n|")) +
"|\n #{'-' * (digits+2) * @size}\n"
end

def solve
half = (@size - 1) / 2 + 1
half.times do |x|
half.times do |y|
@tail = @size * @size
if cc
tail(cc, @tail, *next_pos(x, y))
end
return self if @found
end
end
self
end

private

def valid?(x, y)
x >= 0 && x < @size && y >= 0 && y < @size && !@board[x][y]
end

def nb_exit(x, y)
MOVES.inject(0) { |m, (i, j)| valid?(x+i, y+j) ? m+1 : m }
end

def next_pos(x, y)
MOVES.map { |i,j| [x+i, y+j] }.
select  { |i,j| valid?(i, j) }.
sort_by { |i,j| nb_exit(i, j)} [0]
end

def head(tail, nb, x, y=nil)
@found = true if @head >= @tail
return if @found || !x
@board[x][y] = nb
tail = callcc { |cc|
return cc if !tail
tail.call cc
}
head(tail, nb+1, *next_pos(x, y))
end

def tail(head, nb, x, y=nil)
@tail = nb
@found = true if @head >= @tail
return if @found || !x
@board[x][y] = nb
head = callcc { |cc|