我使用递归方法编写了一个Sudoku解算器。它看起来像这样:
def solve(index = @board.key("-"), board_so_far = @board)
if !board_so_far.has_value?("-")
@solution = board_so_far
return true
elsif available_nums_to_place(index, board_so_far).any?
available_nums_to_place(index, board_so_far).each do |num|
board_so_far[index] = num
solve(board_so_far.key("-"), Marshal.load(Marshal.dump(board_so_far)))
end
else
return false
end
end
一旦找到解决方案,它将在@solution
中保存解决方案。当发生这种情况时,我想停止所有剩余的递归。现在,solve
方法在通过解释其他堆栈已经找到解决方案之后需要的时间大约是它所需的两倍。我如何杀死其余的堆栈?我使用break
代替我的return
,解释器抛出
无效的break runner.rb:编译错误(SyntaxError)
错误。
以下是我希望足够清晰的完整代码,无需进一步解释。
class Sudoku
def initialize(board_string)
@board = to_hash(board_string)
@solution = {}
end
private
def to_hash(board_string)
output_hash = {}
board_array = board_string.split("")
board_array.each_with_index do |char,i|
char == "-" ? output_hash[i] = "-" : output_hash[i] = char.to_i
end
output_hash
end
def row_number(index)
row_number = index/9
end
def column_number(index)
column_number = index % 9
end
def indices_of_row(index)
starting_index = row_number(index) * 9
row_indices = (starting_index...starting_index + 9).to_a
row_indices.delete(index)
row_indices
end
def indices_of_column(index)
column_indices = 0.upto(8).map { |row| row * 9 + column_number(index) }
column_indices.delete(index)
column_indices
end
def grid_coords(index)
[row_number(index) / 3, column_number(index) / 3]
end
def top_left_corner_index(coords)
coords[1] * 3 + coords[0] * 27
end
def indices_of_grid(index)
i = top_left_corner_index(grid_coords(index))
position_adjustment = [0,1,2,9,10,11,18,19,20]
indices_of_grid = position_adjustment.map { |num| num + i }
indices_of_grid.delete(index)
indices_of_grid
end
def available_nums(indices, board)
value_array = indices.map { |index| board[index] }
complete = (1..9).to_a
unplaced_nums = complete - value_array
end
def available_nums_to_place(index, board)
row_values = available_nums( indices_of_row(index), board )
column_values = available_nums( indices_of_column(index), board )
grid_values = available_nums( indices_of_grid(index), board )
end
public
def solve(index = @board.key("-"), board_so_far = @board)
if !board_so_far.has_value?("-")
@solution = board_so_far
return true
elsif available_nums_to_place(index, board_so_far).any?
available_nums_to_place(index, board_so_far).each do |num|
board_so_far[index] = num
solve(board_so_far.key("-"), Marshal.load(Marshal.dump(board_so_far)))
end
else
return false
end
end
# Returns a string representing the current state of the board
def to_s
puts "+-----------------------+"
puts "| SUDOKU! |"
puts "+-----------------------+"
three_rows = @solution.values.each_slice(27).map { |rows| rows }
three_rows.each do |three_rows|
three_rows.each_slice(9) do |row|
printf("| %s %s %s | %s %s %s | %s %s %s |\n", row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8] )
end
puts "|-----------------------|\n"
end
end
end
sudoku_strings = File.read('sudoku_puzzles.txt')
sudoku_arrays = sudoku_strings.split("\n")
sudokus_to_solve = sudoku_arrays.take(1)
sudokus = sudokus_to_solve.map do |unsolved_board|
Sudoku.new(unsolved_board)
end
sudokus.each do |sudoku|
sudoku.solve
sudoku.to_s
end
答案 0 :(得分:0)
更改行
solve(board_so_far.key("-"), Marshal.load(Marshal.dump(board_so_far)))
到
if solve(board_so_far.key("-"), Marshal.load(Marshal.dump(board_so_far)))
return true
end