Assuming a board in the style
b = [
nil, nil, nil, 3, 9, nil, nil, 1, nil,
5, nil, 1, nil, nil, nil, nil, 4, nil,
9, nil, nil, 7, nil, nil, 5, nil, nil,
6, nil, 2, 5, 3, nil, nil, 7, nil,
nil, nil, nil, nil, 7, nil, nil, nil, 8,
7, nil, nil, 8, nil, nil, 9, nil, 3,
8, nil, 3, nil, 1, nil, nil, 9, nil,
nil, 9, nil, 2, nil, 6, nil, nil, 7,
4, nil, nil, nil, nil, 3, nil, 6, 1,
]
It can be solved with 197 bytes...
a=->r{!r.any?{|c|c.compact.uniq!}}
def s r,n=3
[*r.each_slice n]
end
t=[b]
p t.find{|b|j=b.index nil
!j||!9.times{|i|b[j]=i+1;r=s b,9;a[r]&a[r.transpose]&a[s (s s b).transpose.flatten,9]&&t<<[*b]}}
Verbose version:
def section_valid?(section)
section.compact == section.compact.uniq
end
def board_valid?(board)
rows = board.each_slice(9)
rows.all?{ |r| section_valid?(r) } &&
rows.to_a.transpose.all?{ |c| section_valid?(c) } &&
board.each_slice(3).each_slice(3).to_a.transpose.flatten.each_slice(9).all?{ |c| section_valid?(c.flatten) }
end
stack = [board]
until stack.empty?
board = stack.pop
j = board.find_index(nil)
if j.nil?
p board
break
end
(1..9).each{ |i| b = board.dup; b[j] = i; stack.push(b) if board_valid?(b) }
end