require 'matrix'
class Sudoku
def initialize(array)
@array = array
end
def is_valid
#判断是否为正方形的二维数组
@array.each do |ele|
return false if ele.size != @array.size
end
#判断行数和列数开方后是否为整数,因为是正方形,只需要判断行数
m = Matrix[*@array]
size = m.row_count
return false if Math::sqrt(size) != Math::sqrt(size).ceil
#判断每一行和每一列每个数字只出现1次,例如4x4的数独,每一行和每一列是否都是由1、2、3、4组成
#先根据数独的长度得到一个正则,比如9x9,那么正则就是/^123456789$/
string = (1..size).to_a.join("")
reg = Regexp.new "^#{string}$"
(0..size-1).each do |i|
#把每一行和每一列的数字先排序再转成字符串,再去与正则表达式匹配,如果能匹配,则正确
return false unless !!(m.row(i).sort.join =~ reg)
return false unless !!(m.column(i).sort.join =~ reg)
end
#判断每个子数独中每个数字只出现1次,例如4x4的数独,那么其中的2x2的数独中是否都是由1、2、3、4组成
sub_size = Math::sqrt(size).ceil
0.step(size-1,sub_size) do |i|
0.step(size-1,sub_size) do |j|
#把子数独中的数字先排序再转成字符串,再去与正则表达式匹配,如果能匹配,则正确
return false unless !!(m.minor(i..i+sub_size-1,j..j+sub_size-1).to_a.flatten.sort.join =~ reg)
end
end
return true
end
end
goodSudoku1 = Sudoku.new([
[7,8,4, 1,5,9, 3,2,6],
[5,3,9, 6,7,2, 8,4,1],
[6,1,2, 4,3,8, 7,5,9],
[9,2,8, 7,1,5, 4,6,3],
[3,5,7, 8,4,6, 1,9,2],
[4,6,1, 9,2,3, 5,8,7],
[8,7,6, 3,9,4, 2,1,5],
[2,4,3, 5,6,1, 9,7,8],
[1,9,5, 2,8,7, 6,3,4]
])
p goodSudoku1.is_valid
goodSudoku2 = Sudoku.new([[1,4, 2,3],[3,2, 4,1],[4,1, 3,2],[2,3, 1,4]])
p goodSudoku2.is_valid
下面的也可以
require 'matrix'
def done_or_not(board)
#your code here
return false unless board.size == 9
board.each {|e| return false unless e.size == 9}
m = Matrix[*board]
for i in 0..m.row_size - 1
return false unless m.row(i).reduce(:+) == 45
end
for j in 0..m.column_size - 1
return false unless m.column(j).reduce(:+) == 45
end
0.step(6,3) do |i|
0.step(6,3) do |j|
return false unless m.minor(i..i+2, j..j+2).reduce(:+) == 45
end
end
return true
end