Last active
August 29, 2015 14:22
-
-
Save ryandgoldenberg1/b6aa05e0f434e5666d2f to your computer and use it in GitHub Desktop.
Sudoku solver
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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