Skip to content

Instantly share code, notes, and snippets.

@thomasfedb
Created May 11, 2010 09:39
Show Gist options
  • Save thomasfedb/397122 to your computer and use it in GitHub Desktop.
Save thomasfedb/397122 to your computer and use it in GitHub Desktop.
# sudoku.rb
# A program to solve sodoku.
require './includes/utill.rb'
require './includes/cell.rb'
require './includes/group.rb'
require './includes/puzzle.rb'
class Sudoku
def initialize
@puzzle = Puzzle.new
end
def sample
".2.178.3..4.3.2.9.1.......6..86.35..3.......4..67.92...8.9.1.6..1.436.5."
end
def show
print @puzzle.to_s
end
# Read in sudoku data
def read(data)
data.gsub!(".", "0")
data.delete! '^0-9_'
grid_data = data.split("")
(0..80).to_a.each do |cell|
if grid_data[cell].to_i != 0
@puzzle.set_cell(cell, grid_data[cell].to_i)
end
end
end
# Now we have the data, the solving begings!
def solve
end
#private
def reduce
end
def hidden_singles
end
[:solved?, :to_s, :to_grid].each do |method|
define_method method do
@puzzle.call(method)
end
end
private
[:cells, :each_cell, :groups, :each_group].each do |method|
define_method method do
@puzzle.call(method)
end
end
end
# utill.rb
class Array
define_method "/" do |len|
a = []
each_with_index do |x,i|
a << [] if i % len == 0
a.last << x
end
a
end
def count(item)
count = 0
each do |x|
if x == item
count += 1
end
end
count
end
end
# puzzle.rb
class Puzzle
attr_reader :cells, :groups
def initialize
@grid_numbers = (0..80).to_a
@cells = []
@grid_numbers.each do |cell|
@cells[cell] = Cell.new(cell)
end
@groups = []
row_contents = @grid_numbers / 9
column_contents = []
(0..8).to_a.each do |x|
column_contents[x] = []
row_contents.each do |row|
column_contents[x] << row[x]
end
end
box_contents = []
3.times do |x|
row_a = row_contents[x * 3] / 3
row_b = row_contents[x * 3 + 1] / 3
row_c = row_contents[x * 3 + 2] / 3
3.times do |y|
box_contents << row_a[y] + row_b[y] + row_c[y]
end
end
group_contents = box_contents + row_contents + column_contents
group_contents.each do |group|
children = []
group.each do |child_index|
children << @cells[child_index]
end
@groups << Group.new(children)
end
puts @groups.inspect
@groups.each do |group|
group.setup
end
end
def each_cell
@cells.each do |cell|
yeild(cell)
end
end
def each_group
@groups.each do |group|
yeild(group)
end
end
def get_cell(x, y)
@cells[x + 9 * y]
end
def set_cell(pos, value)
@cells[pos].must_be(value)
end
def solved?
@grid_numbers.each do |cell|
if not @cells[cell].solved?
return false
end
end
true
end
def to_grid
grid = []
(0..8).to_a.each do |y|
grid[y] = []
(0..8).to_a.each do |x|
if get_cell(x, y).solved?
grid[y][x] = get_cell(x, y).value
else
grid[y][x] = nil
end
end
end
grid
end
def to_s
out = ""
grid.each do |row|
row.each do |cell|
if cell == nil
out << ". "
else
out << cell.to_s << " "
end
end
out << "\n"
end
out
end
end
# cell.rb
class Position
attr_reader :id
def initialize(id)
@id = id
end
def x
@id % 9
end
def y
(@id / 9).floor
end
end
class Cell
attr_reader :parents, :position
def initialize(id)
@possible = (1..9).to_a
@parents = []
@id = Position.new(id)
end
def cant_be(value)
@possible.delete value
end
def must_be(value)
@possible = [value]
each_sibling do |sibling|
sibling.cant_be(value)
end
each_parent do |parent|
parent.used(value)
end
end
def solved?
@possible.size == 1
end
def can_be
@possible
end
def value
@possible.first if solved?
end
def each_parent
@parents.each do |parent|
yeild(parents)
end
end
def belongs_to(parent)
@parents << parent
end
def siblings
siblings = []
@parents.each do |parent|
siblings.concat(parent.children)
end
slibings.uniq!.delete self
end
def each_sibling
siblings.each do |sibling|
yeild(sibling)
end
end
end
# group.rb
class Group
attr_reader :children
def initialize(children)
@children = children
@unused = (1..9).to_a
end
def setup
@children.each do |child|
child.belongs_to(self)
end
end
def each_child
@children.each do |child|
yeild(child)
end
end
def used(value)
@unused.delete value
if @unused.size == 1
each_child do |child|
if not child.solved?
child.must_be(@unused.first)
end
end
end
end
def solved?
@unused.empty?
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment