example/sudoku-set.rb in gecoder-0.7.1 vs example/sudoku-set.rb in gecoder-0.8.0
- old
+ new
@@ -6,19 +6,18 @@
# http://www.gecode.org/gecode-doc-latest/sudoku-set_8cc-source.html .
class SudokuSet < Gecode::Model
# Takes a 9x9 matrix of values in the initial sudoku, 0 if the square is
# empty.
def initialize(predefined_values)
- unless predefined_values.column_size == 9 and
- predefined_values.row_size == 9
- raise ArgumentError, 'The matrix with predefined values must have ' +
- 'dimensions 9x9.'
+ # Verify that the input is of a valid size.
+ @size = n = predefined_values.row_size
+ block_size = Math.sqrt(n).round
+ unless predefined_values.square? and block_size**2 == n
+ raise ArgumentError, 'Incorrect value matrix size.'
end
+ sub_count = block_size
- @size = n = predefined_values.row_size
- sub_matrix_size = Math.sqrt(n).round
-
# Create one set per assignable number (i.e. 1..9). Each set contains the
# position of all squares that the number is located in. The squares are
# given numbers from 1 to 81. Each set therefore has an empty lower bound
# (since we have no guarantees where a number will end up) and 1..81 as
# upper bound (as it may potentially occurr in any square). We know that
@@ -37,21 +36,25 @@
# Build arrays containing the square positions of each row and column.
rows = []
columns = []
n.times do |i|
- rows << ((i*n + 1)..(i*n + 9))
- columns << [1, 10, 19, 28, 37, 46, 55, 64, 73].map{ |e| e + i }
+ rows << ((i*n + 1)..(i*n + n))
+ columns << (0...n).map{ |e| e*n + 1 + i }
end
# Build arrays containing the square positions of each block.
blocks = []
- sub_matrix_size.times do |i|
- sub_matrix_size.times do |j|
- blocks << [1, 2, 3, 10, 11, 12, 19, 20, 21].map{ |e| e + (j*27)+(i*3) }
+ # The square numbers of the first block.
+ first_block = (0...block_size).map do |e|
+ ((n*e+1)..(n*e+block_size)).to_a
+ end.flatten
+ block_size.times do |i|
+ block_size.times do |j|
+ blocks << first_block.map{ |e| e + (j*n*block_size)+(i*block_size) }
end
end
-
+
# All sets must be pairwise disjoint since two numbers can't be assigned to
# the same square.
n.times do |i|
(i + 1).upto(n - 1) do |j|
@sets[i].must_be.disjoint_with @sets[j]
\ No newline at end of file