8/19/2014 - 2:56 AM

Easy-level solver for sudoku

Easy-level solver for sudoku

``````class Sudoku

def initialize(board_string)
@board = board_string.split("")
end

def solve!
return self if solved?
board.each_with_index do |cell, cell_index|
# next unless cell == '0'
replace_cell_if_only_answer_at cell_index if cell == "0"
end
solve! # did this instead of #until because I prefer a dead stack to an infinite loop, just in case
end

private

attr_accessor :board # made this private because I never need to call #board outside this class

def solved?
!board.include?('0')
end

board[index] = candidates.first if candidates.length == 1
end

#useful article on array manipulation http://blog.endpoint.com/2011/06/using-set-operators-with-ruby-arrays.html
[*"1".."9"] - ( row(index) | col(index) | box(index) )
end

# These methods return a single array from
# their collections for a given spot on the board

def row index
rows[index / 9]
end

def col index
columns[index % 9]
end

def box index
boxes[ find_box_index_for(index) ]
end

# These methods return 2D arrays of our board's
# rows, columns and boxes

def rows
board.each_slice(9).to_a
end

def columns
board.each_slice(9).to_a.transpose
end

def boxes
boxes = Array.new(9) { Array.new }
board.each_with_index do |cell, cell_index|
boxes[ find_box_index_for(cell_index) ].push cell
end
boxes
end

def find_box_index_for index
(index / 9 / 3 * 3) + (index % 9 / 3)
end

def to_s
board.each_slice(9).to_a.map { |row| row.join(' ') }.join("\n")
end

end

# The file has newlines at the end of each line, so we call
# String#chomp to remove them.