How to resolve the algorithm N-queens problem step by step in the Ruby programming language
Published on 12 May 2024 09:40 PM
How to resolve the algorithm N-queens problem step by step in the Ruby programming language
Table of Contents
Problem Statement
Solve the eight queens puzzle.
You can extend the problem to solve the puzzle with a board of size NxN. For the number of solutions for small values of N, see OEIS: A000170.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm N-queens problem step by step in the Ruby programming language
The provided Ruby code contains two different solutions for the "N-Queens" problem, where the goal is to place n
queens on an n x n
chessboard in a way that no two queens threaten each other, meaning they are not in the same row, column, or diagonal.
n_queens Function:
- This function takes an integer
n
as input, wheren
represents the size of the chessboard. - It follows a mathematical sequence to generate a list of numbers
nums
. This list will determine the row placement of queens on the chessboard. - The sequence considers various conditions based on the remainder when
n
is divided by 12. - Finally, it returns a string representation of the chessboard with queens placed in the correct positions.
Queen Class:
- This class uses backtracking to solve the N-Queens problem.
- It initializes with a
num
parameter, which defaults to 8 (for an 8x8 chessboard) and anout
parameter to control whether the solutions are printed. - It defines private helper methods for checking diagonal threats and solving the problem.
- The
solve
method recursively tries different row placements for queens and checks for conflicts. - When a valid solution is found, it increments a
count
variable and prints the solution ifout
is true.
Implementation:
- The code loops through different values of
n
and calls either then_queens
function or theQueen
class to solve the N-Queens problem. - For small values of
n
(1 to 6), it prints the solutions and counts the total number of solutions. - For larger values of
n
(7 to 12), it disabl es printing and only counts the solutions.
Source code in the ruby programming language
# 1. Divide n by 12. Remember the remainder (n is 8 for the eight queens
# puzzle).
# 2. Write a list of the even numbers from 2 to n in order.
# 3. If the remainder is 3 or 9, move 2 to the end of the list.
# 4. Append the odd numbers from 1 to n in order, but, if the remainder is 8,
# switch pairs (i.e. 3, 1, 7, 5, 11, 9, …).
# 5. If the remainder is 2, switch the places of 1 and 3, then move 5 to the
# end of the list.
# 6. If the remainder is 3 or 9, move 1 and 3 to the end of the list.
# 7. Place the first-column queen in the row with the first number in the
# list, place the second-column queen in the row with the second number in
# the list, etc.
def n_queens(n)
if n == 1
return "Q"
elsif n < 4
puts "no solutions for n=#{n}"
return ""
end
evens = (2..n).step(2).to_a
odds = (1..n).step(2).to_a
rem = n % 12 # (1)
nums = evens # (2)
nums.rotate if rem == 3 or rem == 9 # (3)
# (4)
if rem == 8
odds = odds.each_slice(2).flat_map(&:reverse)
end
nums.concat(odds)
# (5)
if rem == 2
nums[nums.index(1)], nums[nums.index(3)] = nums[nums.index(3)], nums[nums.index(1)]
nums << nums.delete(5)
end
# (6)
if rem == 3 or rem == 9
nums << nums.delete(1)
nums << nums.delete(3)
end
# (7)
nums.map do |q|
a = Array.new(n,".")
a[q-1] = "Q"
a*(" ")
end
end
(1 .. 15).each {|n| puts "n=#{n}"; puts n_queens(n); puts}
class Queen
attr_reader :count
def initialize(num=8, out=true)
@num = num
@out = out
@row = *0...@num
@frame = "+-" + "--" * @num + "+"
@count = 0
add = Array.new(2 * @num - 1, true) # \ direction check
sub = Array.new(2 * @num - 1, true) # / direction check
solve([], add, sub)
end
private
def solve(row, add, sub)
y = row.size
if y == @num
print_out(row) if @out
@count += 1
else
(@row-row).each do |x|
next unless add[x+y] and sub[x-y]
add[x+y] = sub[x-y] = false
solve(row+[x], add, sub)
add[x+y] = sub[x-y] = true
end
end
end
def print_out(row)
puts @frame
row.each do |i|
line = @num.times.map {|j| j==i ? "Q " : ". "}.join
puts "| #{line}|"
end
puts @frame
end
end
(1..6).each do |n|
puzzle = Queen.new(n)
puts " #{n} Queen : #{puzzle.count}"
end
(7..12).each do |n|
puzzle = Queen.new(n, false) # do not display
puts " #{n} Queen : #{puzzle.count}"
end
You may also check:How to resolve the algorithm Trabb Pardo–Knuth algorithm step by step in the Ksh programming language
You may also check:How to resolve the algorithm Vigenère cipher step by step in the Action! programming language
You may also check:How to resolve the algorithm Add a variable to a class instance at runtime step by step in the Io programming language
You may also check:How to resolve the algorithm Date manipulation step by step in the Lua programming language
You may also check:How to resolve the algorithm Sudoku step by step in the SAS programming language