Created
June 10, 2013 05:24
-
-
Save andmcgregor/5746717 to your computer and use it in GitHub Desktop.
Brute force sudoku (work in progress). Need to:
- make the code ALOT more efficient. I have a few ideas how to do this.
- improve found algorithm to actually check that the board is solved (rather than just adding up the numbers and seeing if they equal 405).
- pause the search once a solution is found.
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 SudokuCell | |
attr_accessor :index, :value, :row, :column, :box | |
def initialize(initial_value, index) | |
@value = initial_value != 0 ? initial_value : 0 | |
@index = index.to_i | |
@row = (0..81).to_a[((index/9)*9..(index/9)*9+8)] | |
@column, at_index, incrementor = [], index, +9 | |
until @column.count == 9 do | |
if at_index < 0 | |
incrementor = +9 | |
elsif at_index > 80 | |
incrementor = -9 | |
else | |
@column << at_index if [email protected]?(at_index) | |
end | |
at_index += incrementor | |
end | |
@box = get_box | |
end | |
def get_box | |
box_indexes = [[0,1,2,9,10,11,18,19,20],[3,4,5,12,13,14,21,22,23],[6,7,8,15,16,17,24,25,26],[27,28,29,36,37,38,45,46,47],[30,31,32,39,40,41,48,49,50],[33,34,35,42,43,44,51,52,53],[54,55,56,63,64,65,72,73,74],[57,58,59,66,67,68,75,76,77],[60,61,62,69,70,71,78,79,80]] | |
box_indexes.each do |box| | |
return box if box.include?(@index) | |
end | |
end | |
end | |
class Sudoku | |
attr_accessor :counter | |
def initialize(board_string) | |
@counter = 1 | |
i = -1 | |
@board = board_string.chomp.split("").map {|value| i += 1; SudokuCell.new(value.to_i, i) } | |
end | |
def solved? | |
sum = 0 | |
@board.each {|cell| sum += cell.value if cell.value.is_a? Integer } | |
sum == 405 | |
end | |
def solve! | |
count = @board.select {|cell| cell.value == 0 }.size | |
#print_sudoku_and_trace([0,0,0,0,0,0,0,0,0,0,0]) | |
recursive(count) | |
end | |
def recursive(trace = [], length) | |
if length != 0 | |
length -= 1 | |
(1..9).each do |x| | |
temp_trace = trace.clone << x | |
recursive(temp_trace, length) | |
temp_trace = [] | |
end | |
else | |
puts "\e[H\e[2J" if @counter % 50000 == 0 | |
puts print_sudoku_and_trace(trace) if @counter % 50000 == 0 | |
puts "Recursions: #{@counter}" if @counter % 50000 == 0 | |
@counter += 1 | |
end | |
end | |
def print_sudoku_and_trace(trace) | |
counter = 0 | |
trace_counter = 0 | |
str = "" | |
board = @board.clone | |
board.each do |cell| | |
if cell.value != 0 | |
str += cell.value.to_s + " " | |
counter += 1 | |
else | |
str += trace[trace_counter].to_s + " " | |
trace_counter += 1 | |
counter += 1 | |
end | |
if counter % 9 == 0 | |
str += "\n" | |
end | |
end | |
puts str | |
end | |
def to_s | |
board = @board.clone | |
str = "" | |
9.times do | |
board.shift(9).each do |cell| | |
str += cell.value.to_s + " " | |
end | |
str += "\n" | |
end | |
str | |
end | |
end | |
game = Sudoku.new('096040001100060004504810390007950043030080000405023018010630059059070830003590007') | |
game.solve! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment