How to Use the Sudoku Module in Ruby to Solve Puzzles?

  • Thread starter Thread starter sean1234
  • Start date Start date
  • Tags Tags
    Program Ruby
Click For Summary

Discussion Overview

The discussion revolves around the use of a Ruby module designed to solve Sudoku puzzles. Participants explore the implementation details of the code, its execution, and the necessary steps to run it effectively. The conversation includes aspects of coding, debugging, and understanding the module's functionality.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Homework-related

Main Points Raised

  • One participant shares a Ruby code snippet for a Sudoku module and expresses confusion about running it in the terminal.
  • Another participant points out that the code is from a specific example in a Ruby programming book and suggests checking the comments for clarity.
  • A participant expresses uncertainty about the purpose of the module, indicating a lack of understanding of what it means to "solve Sudoku puzzles."
  • Further clarification is provided regarding how to use the module, including a suggested filename and the need to supply an input filename when running the code.

Areas of Agreement / Disagreement

Participants do not reach a consensus on the clarity of the code's purpose and execution. There are varying levels of understanding regarding the module's functionality and how to properly run it.

Contextual Notes

Some participants may have different levels of familiarity with Ruby and programming concepts, which affects their understanding of the module and its usage.

Who May Find This Useful

Readers interested in Ruby programming, particularly those looking to implement or understand Sudoku-solving algorithms, may find this discussion beneficial.

sean1234
Messages
40
Reaction score
0
I wrote the below code in a text editor, saved it as foo.rb Now I assume to run it, I simply go into the terminal and enter ruby foo.rb, yet nothing happens.

module Sudoku

class Puzzle
ASCII = ".123456789"
BIN = "\000\001\002\003\004\005\006\007\010\011"
def initialize(lines)
if (lines.respond_to? :join)
s = lines.join
else
s = lines.dup
end
s.gsub!(/\s/, "") # /\s/ is a Regexp that matches any whitespace

raise Invalid, "Grid is the wrong size" unless s.size == 81
if i = s.index(/[^123456789\.]/)
raise Invalid, "Illegal character #{s[i,1]} in puzzle"
end
s.tr!(ASCII, BIN)
@grid = s.unpack('c*')

raise Invalid, "Initial puzzle has duplicates" if has_duplicates?
end
def to_s
(0..8).collect{|r| @grid[r*9,9].pack('c9')}.join("\n").tr(BIN,ASCII)
end
def dup
copy = super
@grid = @grid.dup
copy
end
def [](row, col)
@grid[row*9 + col]
end
def []=(row, col, newvalue)
unless (0..9).include? newvalue
raise Invalid, "illegal cell value"
end
@grid[row*9 + col] = newline
end
BoxOfIndex = [
0,0,0,1,1,1,2,2,2,0,0,0,1,1,1,2,2,2,0,0,0,1,1,1,2,2,2,
3,3,3,4,4,4,5,5,5,3,3,3,4,4,4,5,5,5,3,3,3,4,4,4,5,5,5,
6,6,6,7,7,7,8,8,8,6,6,6,7,7,7,8,8,8,6,6,6,7,7,7,8,8,8
].freeze
def each_unknown
0.upto 8 do |row|
0.upto 8 do |col|
index = row*9+col
next if @grid[index] !=0
box = BoxofIndex[index]
yield row, col, box
end
end
end
def has_duplicates?
0.upto(8) {|row| return true if rowdigits(row).uniq! }
0.upto(8) {|col| return true if coldigits(col).uniq! }
0.upto(8) {|box| return true if boxdigits(box).uniq! }
false
end
AllDigits = [1,2,3,4,5,6,7,8,9].freeze
def possible(row, col, box)
AllDigits - (rowdigits(row) + coldigits(col) + boxdigits(box))
end
private
def rowdigits(row)
@grid[row*9,9] - [0]
end
def coldigits(col)
result = []
col.step(80, 9) {|i|
v = @grid
result << v if (v != 0)
}
result
end
BoxToIndex = [0, 3, 6, 27, 30, 33, 54, 57, 60].freeze
def boxdigits(b)
i = BoxToIndex
[
@grid, @grid[i+1], @grid[i+2],
@grid[i+9], @grid[i+10], @grid[i+11],
@grid[i+18], @grid[i+19], @grid[i+20]
] - [0]
end
end
class Invalid < StandardError
end
class Impossible < StandardError
end
def Sudoku.scan(puzzle)
unchanged = false
until unchanged
unchanged = true
rmin,cmin,pmin = nil
min = 10
puzzle.each_unknown do |row, col, box|
case p.size
when 0
raise Impossible
when 1
puzzle[row,col] = p[0]
unchanged = false
else
if unchanged && p.size < min
min = p.size
rmin, cmin, pmin = row, col, p
end
end
end
end
return rmin, cmin, pmin
end
def Sudoku.solve(puzzle)
puzzle = puzzle.dup
r,c,p = scan(puzzle)
return puzzle if r == nil
p.each do |guess|
puzzle[r,c] = guess

begin
return solve(puzzle)
rescue Impossible
next
end
end
raise Impossible
end
end
 
Technology news on Phys.org
Although you didn't make this clear, that code is from Example 1-1 of "The Ruby Programming Language" by David Flanagan and Yukihiro Matsumoto. Did you try reading the very first comment in the example?
 
I guess that was a bit unclear for me. It says that it is a "module to solve Sudoku puzzles." I am not really certain what exactly that is.
 
I was referring to this:

Code:
# Use this module to solve Sudoku puzzles with code like this:
#
#  require 'sudoku'
#  puts Sudoku.solve(Sudoku::Puzzle.new(ARGF.readlines))

Put that in a new file called "sudoku_solver.rb" or something and run it. You'll need to supply the input filename on the command line.
 

Similar threads

  • · Replies 6 ·
Replies
6
Views
3K