Skip to content

Instantly share code, notes, and snippets.

@sanchojaf
Last active April 9, 2018 00:35
Show Gist options
  • Save sanchojaf/8eb9fdc7bdec2616756daf753fa2d093 to your computer and use it in GitHub Desktop.
Save sanchojaf/8eb9fdc7bdec2616756daf753fa2d093 to your computer and use it in GitHub Desktop.
N-queens problem [backtracking, ruby]
# The n-queens problem is to find all possible ways to place n queens(Q) on an n ×
# n chess board in such a way that no two queens share a row, column, or
# diagonal. The diagram at right shows one way that can be done on a standard 8
# × 8 chess board.
class Board
def initialize(n)
@n = n
@board = Array.new(n) { Array.new(n, false) }
end
def solve
start_row 0
end
def start_row(row)
0.upto(@n-1) do |col|
next unless safe?(row, col)
@board[row][col] = true
row == @n-1 ? print_board : start_row(row+1)
@board[row][col] = false
end
end
def safe?(row, col)
safe_horz_and_vert?(row, col) && safe_all_diag?(row, col)
end
def safe_horz_and_vert?(row, col)
0.upto(@n-1) do |index|
return false if @board[index][col] || @board[row][index]
end
true
end
def safe_all_diag?(row, col)
variations = [[1,1],[1,-1],[-1,1],[-1,1]]
variations.each do |row_mod, row_mod|
return false unless safe_diag?(row, col, row_mod, col_mod)
end
true
end
def safe_diag?(row, col, row_mod, col_mod)
other_row, other_col = row+row_mod, col+col_mod
while other_row.between?(0,@n-1) && other_col.between?(0,@n-1) do
return false if @board[other_row][other_col]
other_row += row_mod
other_col += col_mod
end
true
end
def print_board
puts "Board:"
@board.each do |row|
row.each do |value|
print value ? 'Q' : '.'
end
puts
end
end
end
# Solve the problem for 4 queens. There should be 2 solutions.
board = Board.new(4).solve
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment