Skip to content

Instantly share code, notes, and snippets.

@kmandreza
Last active December 12, 2015 03:38
Show Gist options
  • Save kmandreza/4708277 to your computer and use it in GitHub Desktop.
Save kmandreza/4708277 to your computer and use it in GitHub Desktop.
Teacher's solution for Sudoku_solver
=begin
#PSEUDOCODE FOR PHASE 2
solve!
#STEP 1...next step is either step 2 or 3
return false if board is valid
valid? => checks for duplicates
if attempt causes some repetition of number
#STEP 2...
return board if solved?
solved? => check for no empty spaces #solved means it is valid and no empty spaces
#STEP 3...
if not solved or valid, the space is 'without a doubt' empty
first find first empty space
put each of those numbers from 1..9 and try to solve it #this is big... this is where the previous methods are reused
(1..9).each |value|
put value in empty space
create a new game
solve it
=end
class Sudoku
attr_reader :board
def initialize(board)
@board = board.split("")
prepare_row_columns_boxes
puts @rows.inspect
puts @columns.inspect
puts @boxes.inspect
puts valid?
end
def solve!
return false unless valid?
return @board.join if solved?
next_empty_index = @board.index("0")
(1..9).each do |attempt|
@board[next_empty_index] = attempt
solution = Sudoku.new(@board.join).solve!
return solution if solution
end
return false
end
def valid?
no_dups?(@rows) && no_dups?(@columns) && no_dups?(@boxes)
end
def solved?
@board.count("0") == 0
end
private
def prepare_row_columns_boxes
@rows = Array.new(9) {Array.new}
@columns = Array.new(9) {Array.new}
@boxes = Array.new(9) {Array.new}
@board.each_with_index do |value, index|
next if value == "0"
@rows[row_for(index)].push value
@columns[column_for(index)].push value
@boxes[box_for(index)].push value
end
end
def row_for(index)
index / 9 #BUGBUG
end
def column_for(index)
index % 9 #BUGBUG
end
def box_for(index)
box_column_co = column_for(index) / 3
row_column_co = row_for(index) / 3
box_column_co + (row_column_co * 3)
# (column_for(index) / 3) + ((row_for(index) / 3) * 3)
end
def no_dups?(set)
set.each do |subset|
return false if subset.uniq.length != subset.length
end
true
end
end
game = Sudoku.new('003020600900305001001806400008102900700000008006708200002609500800203009005010300')
puts game.solve!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment