Skip to content

Instantly share code, notes, and snippets.

@canton7
Last active December 15, 2015 01:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save canton7/5177748 to your computer and use it in GitHub Desktop.
Save canton7/5177748 to your computer and use it in GitHub Desktop.
Golf'd ruby sudoku solver

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment