8女王問題 その2
8女王問題の解法その2
1つの列には1つ以上女王を置けず、かつ1つは女王を置かないといけないという事実からのアルゴリズム。
その1よりかなり効率的。
但し、回転や反転対称は重複して解として出力する。
#!/usr/local/bin/ruby # -*- coding: utf-8 -*- # # queen2.rb #-- セルの数を表す。 #-- 縦、横同じ長さである。 NUMBEROFQUEEN = 8 #-- ボードを表す。 #-- 実際のデータは@boardに格納される。 #-- 各行について女王のいる列を数値で表す。 #-- 空白行は-1、女王がいるセルは0〜NUMBEROFQUEEN-1で表す。 class Queen #-- 初期化 #-- ボードを表す@boardに初期値を設定する。 def initialize @board = [] x = 0 while x < NUMBEROFQUEEN do @board << -1 x = x+1 end end #-- 自身のコピーを生成する。 def dup copy = super @board = @board.dup copy end def set (row, col) @board[row] = col end #-- row番目にcolを入れられるかどうか調べる。 #-- 入れられればtrue、入れれらなければfalseを返す。 #-- row以前にcolと同じ値がないことを確認する。 #-- row以前にcolと斜めでぶつかる値がないかを確認する。 def check(row, col) diff = 0 row.downto(0){ |x| if @board[x] == col return false end if @board[x] == col + diff return false end if @board[x] == col - diff return false end diff = diff+1 } true end #-- ボードを縦横並べて表示する。 def print_board print @board, "\n" end end #-- END OF CLASS Queen #----------------------------------- #-- 再帰的にsolveを呼び出し、解を見つける。 #-- 女王が置けたら女王を置いた盤を生成し更にsolveを実行する。 def solve(queen, row) if (row >= NUMBEROFQUEEN) print "Solved!! " queen.print_board return end NUMBEROFQUEEN.times{ |col| tmp = queen.dup if (tmp.check(row, col)) tmp.set(row, col) solve(tmp, row+1) end } end # ===================================== a = Queen.new solve(a, 0)