Created
April 24, 2013 16:05
-
-
Save andmcgregor/5453318 to your computer and use it in GitHub Desktop.
First attempt at 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
CELL_POSSIBILITIES = [1, 2, 3, 4, 5, 6, 7, 8, 9] | |
def print_sudoku(example) | |
example.each do |line| | |
line.each do |cell| | |
print cell.to_s + " " | |
end | |
puts | |
end | |
end | |
def sudoku_sum(example) | |
acc = 0 | |
example.each do |line| | |
line.each do |cell| | |
if cell.is_a? Integer | |
acc += cell | |
end | |
end | |
end | |
acc | |
end | |
def solved?(example) | |
if sudoku_sum(example) == 405 | |
true | |
else | |
false | |
end | |
end | |
def solve_sudoku(example) | |
until solved?(example) | |
# Populate empty cells with 1-9 array | |
example.each do |line| | |
line.map! do |cell| | |
if cell.to_s.match(/[1-9]/) | |
cell | |
else | |
CELL_POSSIBILITIES | |
end | |
end | |
end | |
# Remove impossible numbers from array | |
example.each_with_index do |line, index| | |
line.each_with_index do |cell, line_index| | |
if cell.is_a? Integer | |
else | |
impossible = [] | |
# Impossible numbers in same row | |
line.each do |num| | |
if num.is_a? Integer | |
impossible << num | |
end | |
end | |
# Impossible numbers in same column | |
example.each do |line| | |
if line[line_index].is_a? Integer | |
impossible << line[line_index] | |
end | |
end | |
# Impossible numbers in same sub-grid | |
top_left = [[0,0], [0,1], [0,2], [1,0], [1,1], [1,2], [2,0], [2,1], [2,2]] | |
top_middle = [] | |
top_right = [] | |
middle_left = [] | |
middle_middle = [] | |
middle_right = [] | |
bottom_left = [] | |
bottom_middle = [] | |
bottom_right = [] | |
top_left.each do |index| | |
top_middle << [index[0] + 3, index[1]] | |
top_right << [index[0] + 6, index[1]] | |
middle_left << [index[0], index[1] + 3] | |
middle_middle << [index[0] + 3, index[1] + 3] | |
middle_right << [index[0] + 6, index[1] + 3] | |
bottom_left << [index[0], index[1] + 6] | |
bottom_middle << [index[0] + 3, index[1] + 6] | |
bottom_right << [index[0] + 6, index[1] + 6] | |
end | |
if line_index <= 2 | |
#TOP | |
if index <= 2 | |
#LEFT | |
array = top_left | |
elsif index <=5 | |
#MIDDLE | |
array = top_middle | |
else | |
#RIGHT | |
array = top_right | |
end | |
elsif line_index <=5 | |
#MIDDLE | |
if index <= 2 | |
#LEFT | |
array = middle_left | |
elsif index <=5 | |
#MIDDLE | |
array = middle_middle | |
else | |
#RIGHT | |
array = middle_right | |
end | |
else | |
#BOTTOM | |
if index <= 2 | |
#LEFT | |
array = bottom_left | |
elsif index <=5 | |
#MIDDLE | |
array = bottom_middle | |
else | |
#RIGHT | |
array = bottom_right | |
end | |
end | |
array.each do |x, y| | |
if example[x][y].is_a? Integer | |
impossible << example[x][y] | |
end | |
end | |
# Remove impossible values | |
line[line_index] = cell - impossible.uniq | |
end | |
end | |
end | |
# Convert single value arrays to integers | |
example.each do |line| | |
line.each_with_index do |cell, index| | |
if cell.is_a? Array | |
if cell.length == 1 | |
line[index] = cell[0] | |
end | |
end | |
end | |
end | |
end | |
end | |
example = [ | |
[5, 3, 0, 0, 7, 0, 0, 0, 0], | |
[6, 0, 0, 1, 9, 5, 0, 0, 0], | |
[0, 9, 8, 0, 0, 0, 0, 6, 0], | |
[8, 0, 0, 0, 6, 0, 0, 0, 3], | |
[4, 0, 0, 8, 0, 3, 0, 0, 1], | |
[7, 0, 0, 0, 2, 0, 0, 0, 6], | |
[0, 6, 0, 0, 0, 0, 2, 8, 0], | |
[0, 0, 0, 4, 1, 9, 0, 0, 5], | |
[0, 0, 0, 0, 8, 0, 0, 7, 9] | |
] | |
solve_sudoku(example) | |
print_sudoku(example) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment