Skip to content

Instantly share code, notes, and snippets.

@ryandgoldenberg1
Last active August 29, 2015 14:22
Show Gist options
  • Save ryandgoldenberg1/b6aa05e0f434e5666d2f to your computer and use it in GitHub Desktop.
Save ryandgoldenberg1/b6aa05e0f434e5666d2f to your computer and use it in GitHub Desktop.
Sudoku solver
class Sudoku
# board should be a string with numbers and dashes for spaces
def initialize(board)
@board = board.chars.to_a
end
# prints board
def show
(0...9).each {|r|
(0...9).each {|c| print @board[r*9 + c]}
print "\n"
}
puts "\n"
end
# given index, returns array of characters in the same row, column, and box.
# takes advantage of the formulas: row = index / 9 ; column = index % 9
def get_row(idx)
(0...9).map {|i| @board[idx/9*9 + i]}
end
def get_col(idx)
(0...9).map {|i| @board[idx%9 + i*9]}
end
def get_box(idx)
(0...9).map {|i| @board[( (idx/9)/3*3 + i/3)*9 + ((idx%9)/3*3 + i%3 )]}
end
# given index, returns array of possible values
def evaluate(idx)
result = (1..9).map {|i| i.to_s}
result -= get_row(idx) + get_col(idx) + get_box(idx)
result
end
# returns a hash containing indices of all blanks as keys and arrays of possibilities as values
def get_poss
indices = (0...81).select {|i| @board[i] == '-'}
result = {}; indices.each {|idx| result[idx] = evaluate(idx)}
result
end
# recursively solves the sudoku
# returns true if a solution exists, false if it doesn't
def solve
poss = get_poss
if poss.length == 0 then return true end
# find blank with least number of possibilities
k = poss.keys.sort_by {|key| poss[key].length}[0]
v = poss[k]
# test for contradictions
if v.length == 0
return false
elsif v.length == 1
@board[k] = v[0]
return solve
else
# in the case of multiple possibilities, we 1)create a copy of the board, 2)try the next possibility, and
# 3)if it doesn't have a solution we reset the board
old_board = @board.dup
v.each do |n|
@board[k] = n
if solve
return true
else
@board = old_board
end
end
return false
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment