Created
June 25, 2012 22:20
-
-
Save chadwickdonald/2991740 to your computer and use it in GitHub Desktop.
sodoku
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 SudokuBoard | |
def initialize(board_str) | |
@example_board ="123456789578139624496872153952381467641297835387564291719623548864915372235748916" | |
@board = board_str.split("").map { |value| Cell.new(value.to_i) } | |
@groups = [] | |
(generate_rows + generate_cols + generate_grids).each do |group_member_indices| | |
group_cell_members = group_member_indices.map { |index| @board[index] } | |
@groups << Group.new(group_cell_members) | |
end | |
end | |
def pretty_print | |
cell_values_to_print = cell_values | |
while !cell_values_to_print.empty? | |
line = cell_values_to_print.slice!(0..8) | |
puts line | |
end | |
puts "---------" | |
end | |
def solve | |
puts cell_values | |
while cell_values.include?('0') | |
@board.each do |cell| | |
cell.refresh_state | |
end | |
puts cell_values | |
#pretty_print | |
end | |
cell_values | |
end | |
def cell_values | |
values = [] | |
@board.each { |cell| values << cell.value } | |
values.join | |
end | |
def generate_rows | |
ar = (0..80).to_a | |
rows = [] | |
while !ar.empty? | |
rows << ar.shift(9) | |
end | |
rows | |
end | |
def generate_cols | |
ar = (0..80).to_a | |
cols = Array.new(9,[]) | |
ar.each { |index| cols[index % 9] += [index] } | |
cols | |
end | |
def generate_grids | |
ar = (0..80).to_a | |
grids = Array.new(9,[]) | |
ar.each { |index| grids[(index / 9 / 3 * 3) + ((index % 9) / 3)] += [index]} | |
grids | |
end | |
end | |
class Group | |
def initialize(members_ar) #pass in array of initial board settings | |
@cells = members_ar | |
@cells.each { |cell| cell.add_group(self)} | |
end | |
def other_cells_in_group(cell) | |
@cells - [cell] | |
end | |
end | |
class Cell | |
attr_reader :value, :blacklist | |
def initialize(value) | |
@value = value | |
@groups = [] | |
solved? ? set_value(value) : @blacklist = [] | |
end | |
def set_value(value) | |
@value = value | |
@blacklist = (1..9).to_a - [@value] | |
end | |
def add_group(group) | |
@groups << group | |
end | |
def refresh_state | |
@groups.each do|group| | |
other_cells = group.other_cells_in_group(self) | |
update_blacklist(other_cells.map { |cell| cell.value }) | |
determine_logical_value(other_cells.map { |cell| cell.value }) | |
determine_inferential_value(other_cells.map { |cell| cell.blacklist }) | |
end | |
end | |
def update_blacklist(values_ar) | |
values_ar.each do |value| | |
@blacklist << value unless (@blacklist.include?(value) || value == 0) | |
end | |
end | |
def determine_logical_value(values_ar) | |
if !values_ar.include?(0) | |
set_value(((1..9).to_a - values_ar)[0]) | |
end | |
end | |
def determine_inferential_value(blacklist_ar) | |
surviving_possibilities = (1..9).to_a | |
blacklist_ar.each do |blacklist| | |
surviving_possibilities &= blacklist | |
end | |
if surviving_possibilities.length == 1 | |
set_value(surviving_possibilities[0]) | |
end | |
end | |
def solved? | |
@value > 0 | |
end | |
end | |
class Utils | |
def self.get_files(directory) | |
files = [] | |
Dir.foreach(directory) do |file_name| | |
if !file_name.scan(".unsolved.txt").empty? | |
files << file_name | |
end | |
end | |
files | |
end | |
def self.get_lines_from_file(filename) | |
lines = [] | |
file =File.open(filename, "r") | |
while (line = file.gets) | |
lines << line | |
end | |
lines | |
end | |
def self.write_to_file(filename, text) | |
filename.gsub!("unsolved", "solved") | |
File.open(filename, "a").write(text) | |
end | |
end | |
class Player | |
def play_lots_of_sudoku(directory) | |
files = Utils.get_files(directory) | |
files.each do |file| | |
lines = Utils.get_lines_from_file(file) | |
lines.each do |l| | |
game = SudokuBoard.new(l.chomp) | |
Utils.write_to_file(file, game.solve + "\n") | |
end | |
end | |
end | |
end | |
#board = SudokuBoard.new("619030040270061008000047621486302079000014580031009060005720806320106057160400030") | |
#board = SudokuBoard.new("096040001100060004504810390007950043030080000405023018010630059059070830003590007") | |
#board = SudokuBoard.new("396040001100369004504810396007951043931480005405023918710630459659174832043590167") | |
#board.solve | |
# util = Utils.new | |
# p util.get_files(".") | |
# p util.get_lines_from_file("sodoku1.unsolved.txt") | |
player = Player.new | |
player.play_lots_of_sudoku(".") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment