Ruby 如何从递归方法中删除剩余堆栈

Ruby 如何从递归方法中删除剩余堆栈,ruby,recursion,stack,Ruby,Recursion,Stack,我使用递归方法编写了一个数独解算器。它看起来像这样: 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

我使用递归方法编写了一个数独解算器。它看起来像这样:

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

错误

更新1 下面是完整的代码,我希望它足够清晰,无需进一步解释

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
换线

solve(board_so_far.key("-"), Marshal.load(Marshal.dump(board_so_far)))


您有许多无法解释的方法/变量。这使你的问题最多只能靠猜测来回答。@sawa,欢迎回来@CarySwoveland我只会偶尔参加。我不会在这上面花费太多时间。当然,现在添加它,我只是不想添加任何无关的和令人困惑的代码,因为我认为这个问题足够一般。你能提供包含一个测试问题的数独数组吗?谢谢。然而,我这样做了,在3次递归之后,解释器停止了,没有找到解决方案。
if solve(board_so_far.key("-"), Marshal.load(Marshal.dump(board_so_far)))
  return true
end