sudokusolver 1.3 → 1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. data/lib/sudokusolver.rb +36 -22
  2. metadata +2 -2
@@ -4,19 +4,20 @@
4
4
  # Algorithm, overall structure and original python source code by Peter Norvig
5
5
  # See http://norvig.com/sudoku.html
6
6
 
7
- ## Throughout this program:
8
- ## r is a row, e.g. 'A'
9
- ## c is a column, e.g. '3'
10
- ## s is a square, e.g. 'A3'
11
- ## d is a digit, e.g. '9'
12
- ## u is a unit, e.g. ['A1','B1','C1','D1','E1','F1','G1','H1','I1']
13
- ## g is a grid, e.g. 81 non-blank chars, e.g. starting with '.18...7...
14
- ## values is a hash of possible values, e.g. {'A1'=>'123489', 'A2'=>'8', ...}
7
+ # Throughout this program:
8
+ # r is a row, e.g. 'A'
9
+ # c is a column, e.g. '3'
10
+ # s is a square, e.g. 'A3'
11
+ # d is a digit, e.g. '9'
12
+ # u is a unit, e.g. ['A1','B1','C1','D1','E1','F1','G1','H1','I1']
13
+ # g is a grid, e.g. 81 non-blank chars, e.g. starting with '.18...7...
14
+ # values is a hash of possible values, e.g. {'A1'=>'123489', 'A2'=>'8', ...}
15
15
 
16
16
  class SudokuSolver
17
- VERSION = "1.3"
17
+ VERSION = "1.4"
18
18
  attr_reader :rows, :cols, :squares, :unitlist, :peers, :units
19
19
 
20
+ # Cross-product
20
21
  def cross(a, b)
21
22
  cp = Array.new # cross product
22
23
  a.each do |x|
@@ -60,6 +61,8 @@ class SudokuSolver
60
61
 
61
62
  end
62
63
 
64
+ # A grid is an 81 character string composed of the digits 0-9
65
+ # A blank is represented as a period.
63
66
  def parse_grid(g)
64
67
  g = g.chomp
65
68
  g = g.split('')
@@ -72,6 +75,9 @@ class SudokuSolver
72
75
  return values
73
76
  end
74
77
 
78
+ # Assign a value to a square in the Sudoku grid:
79
+ # Eliminate all other possible digits from the square
80
+ # by calling the eliminate function (mutually recursive)
75
81
  def assign(values, s, d)
76
82
  values[s].split('').each do |d2|
77
83
  unless d2 == d
@@ -81,19 +87,23 @@ class SudokuSolver
81
87
  return values
82
88
  end
83
89
 
90
+ # Remove a possibility from a square.
91
+ # Recursively propagate the constraints: look at the source code for how this is done.
84
92
  def eliminate(values, s, d)
85
93
  return values unless values[s].include?(d) ## Already eliminated.
86
94
 
87
- values[s] = values[s].sub(d,'') ## Remove the digit from the string of possibilities
88
- ## values[s].sub!(d,'') => why doesn't sub!() work?
95
+ values[s] = values[s].sub(d,'') # Remove the digit from the string of possibilities
96
+ # values[s].sub!(d,'') => why doesn't sub!() work?
89
97
 
90
- return false if values[s].length == 0 ## Contradiction: no more values (no more digits can be assigned)
98
+ return false if values[s].length == 0 # Contradiction: no more values (no more digits can be assigned)
91
99
 
92
- ## Remove digit from all peers
100
+ # Remove digit from all peers
101
+ # If the square has only one remaining possibility, that is the assigned value for the square and
102
+ # that value must be removed from all that square's peers.
93
103
  peers[s].each { |s2| return false unless eliminate(values, s2, values[s]) } if values[s].length == 1
94
104
 
95
- ## Assign digit if, by elimination, there is only one square left
96
- ## in the units for this square that can hold the digit
105
+ # Assign the digit to the square if, by elimination
106
+ # this is the only square that has the digit as a possibility
97
107
  units[s].each do |u|
98
108
  dplaces = Array.new
99
109
  u.each { |s2| dplaces << s2 if values[s2].include?(d) }
@@ -103,10 +113,11 @@ class SudokuSolver
103
113
  return values
104
114
  end
105
115
 
116
+ # Search if constraint satisfaction does not solve the puzzle
106
117
  def search(values)
107
118
  return false if values == false
108
119
 
109
- solved = true ## assumption
120
+ solved = true # assumption
110
121
  squares.each do |s|
111
122
  unless values[s].length == 1
112
123
  solved = false
@@ -117,7 +128,7 @@ class SudokuSolver
117
128
 
118
129
  min = 10
119
130
  start = nil
120
- squares.each do |s| ## Chose the undetermined square s with the fewest possibilities
131
+ squares.each do |s| # Chose the undetermined square s with the fewest possibilities
121
132
  l = values[s].length
122
133
  if l > 1 && l < min
123
134
  min = l
@@ -132,6 +143,7 @@ class SudokuSolver
132
143
  return false
133
144
  end
134
145
 
146
+ # Print a text Sudoku grid to STDOUT
135
147
  def print_grid(values)
136
148
  return if values == false
137
149
  max = 0
@@ -163,6 +175,7 @@ class SudokuSolver
163
175
  return values
164
176
  end
165
177
 
178
+ # Transform the solution into an 81 character string
166
179
  def string_solution(values)
167
180
  solution = ""
168
181
  squares.each do |s|
@@ -171,6 +184,7 @@ class SudokuSolver
171
184
  return solution
172
185
  end
173
186
 
187
+ # Verify the Sudoku solution
174
188
  def check_solution(solution)
175
189
  values = Hash.new
176
190
  for s,d in squares.zip(solution.split(''))
@@ -189,9 +203,9 @@ class SudokuSolver
189
203
 
190
204
  end
191
205
 
192
- ## Algorithm by Peter Norvig @ http://www.norvig.com/sudoku.html
206
+ # Algorithm by Peter Norvig @ http://www.norvig.com/sudoku.html
193
207
 
194
- ## More constraints:
195
- ## http://www.scanraid.com/BasicStrategies.htm
196
- ## http://www.krazydad.com/blog/2005/09/29/an-index-of-sudoku-strategies/
197
- ## http://www2.warwick.ac.uk/fac/sci/moac/currentstudents/peter_cock/python/sudoku/
208
+ # More constraints:
209
+ # http://www.scanraid.com/BasicStrategies.htm
210
+ # http://www.krazydad.com/blog/2005/09/29/an-index-of-sudoku-strategies/
211
+ # http://www2.warwick.ac.uk/fac/sci/moac/currentstudents/peter_cock/python/sudoku/
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: sudokusolver
5
5
  version: !ruby/object:Gem::Version
6
- version: "1.3"
7
- date: 2007-04-15 00:00:00 -04:00
6
+ version: "1.4"
7
+ date: 2007-04-22 00:00:00 -04:00
8
8
  summary: Commandline program and library for solving Sudoku puzzles
9
9
  require_paths:
10
10
  - lib