From: Justin Collins Date: 2006-08-14T03:52:22+09:00 Subject: [Solution] re: [QUIZ] Pen and Paper (#90) Here's my solution, which works the same way as Elliot's first solution, although with very different code: It picks a random starting position, then finds all available moves from there, sorts them randomly, then picks the one with the fewest moves available. Without the random sort, you'll always move in a similar pattern. It seems to work a little bit better with the random sort. I also ended up spending some time on getting nice looking output. :) And it could certainly be made more efficient. class Board def initialize(size) @board = Array.new(size) { Array.new(size) { '.' } } @size = size @current = 1 end #Checks if the spot at (x, y) is available def available?(x, y) if x >= 0 and x < @size and y >= 0 and y <= @size @board[x][y] == '.' else false end end #Returns a list of pairs which can be reached from (x, y) def available_from(x, y) available = [[x, y - 3], [x + 2, y - 2], [x + 3, y], [x + 2, y + 2], [x, y + 3], [x - 2, y + 2], [x - 3, y],[x - 2, y - 2]].map { |pair| available?(*pair) ? pair : nil }.compact end #Checks if the board is completed def full? @size**2 < @current end #Marks the spot at (x,y) def mark(x, y) if available?(x, y) @board[x][y] = @current @current += 1 else raise "#{x},#{y} is not available" end end #Nice box output def to_s lines = "-" + "-"*5*@size + "\n" out = "" out << lines @board.each do |row| out << "|" << row.map { |num| num.to_s.rjust(4) }.join(' ') << "|\n" end out << lines end end raise "Please supply size" if ARGV[0].nil? size = ARGV[0].to_i raise "Size must be greater than 4" if size < 5 success = false until success board = Board.new(size) #Pick random starting point x = rand(size) y = rand(size) #Mark the board there board.mark(x,y) success = true #Fill the board until board.full? avail = board.available_from(x, y).sort { rand } #No moves available if avail.empty? puts "Cannot proceed" success = false break end #Pick the best available move best = avail.inject { |best, pair| board.available_from(*pair).length < board.available_from(*best).length ? pair : best } #Mark the board x, y = best board.mark(x, y) end end #Output the solution puts board -Justin