dancing-links 0.1 → 0.1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +46 -0
- data/Rakefile +34 -0
- data/lib/dancing_links.rb +0 -50
- metadata +44 -35
- data/lib/array_combs_perms.rb +0 -59
- data/test/tc_dancing_links.rb +0 -222
data/README.rdoc
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
This module provides an implementation of the "dancing links" algorhthm
|
2
|
+
to solve the "exact cover" problem.
|
3
|
+
|
4
|
+
The "exact cover" problem:
|
5
|
+
- Given a set of vectors containing 0's and 1's:
|
6
|
+
- Find a subset of these vectors that collectively contain one and only one 1 in each and every column.
|
7
|
+
|
8
|
+
For example the follwing set of vectors:
|
9
|
+
- A = [ 0, 1, 0]
|
10
|
+
- B = [ 1, 1, 0]
|
11
|
+
- C = [ 1, 0, 0]
|
12
|
+
- D = [ 0, 0, 1]
|
13
|
+
|
14
|
+
Has two solutions:
|
15
|
+
- A = [ 0, 1, 0]
|
16
|
+
- C = [ 1, 0, 0]
|
17
|
+
- D = [ 0, 0, 1]
|
18
|
+
|
19
|
+
and
|
20
|
+
- B = [ 1, 1, 0]
|
21
|
+
- D = [ 0, 0, 1]
|
22
|
+
|
23
|
+
A better description of the problem can be found here:
|
24
|
+
http://en.wikipedia.org/wiki/Exact_cover
|
25
|
+
|
26
|
+
The "dancing links" algorithm is a commonly used solution for this problem and
|
27
|
+
was found by Donald Knuth. The algorithm involves the construction of a
|
28
|
+
sparse matrix containing nodes that are doubly-linked both horizontally and
|
29
|
+
vertically. The matrix itself simply facilitates the depth-first search
|
30
|
+
(aka backtracking) part of the algorithm.
|
31
|
+
|
32
|
+
The importance of the doubly-linked nodes are that they allow for quick
|
33
|
+
removal/restoration of rows/columns of nodes, which is exactly what a
|
34
|
+
backtracking algorithm for the "exact cover" problem needs.
|
35
|
+
|
36
|
+
horizontal removal:
|
37
|
+
- node.left.right = node.right
|
38
|
+
- node.right.left = node.left
|
39
|
+
|
40
|
+
horizontal restoration:
|
41
|
+
- node.left.right = node
|
42
|
+
- node.right.left = node
|
43
|
+
|
44
|
+
A better description of the algorithm can be found here:
|
45
|
+
http://en.wikipedia.org/wiki/Dancing_Links
|
46
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rubygems/package_task'
|
3
|
+
require 'rdoc/task'
|
4
|
+
|
5
|
+
task :default => [:rdoc, :gem]
|
6
|
+
|
7
|
+
PKG_FILES = FileList['lib/**/*.rb','[A-Z]*']
|
8
|
+
|
9
|
+
gem_spec = Gem::Specification.new do |s|
|
10
|
+
s.platform = Gem::Platform::RUBY
|
11
|
+
s.summary = 'An implementation of "Dancing Links".'
|
12
|
+
s.name = "dancing-links"
|
13
|
+
s.version = "0.1.0.1"
|
14
|
+
s.authors = ["Justin W Smith"]
|
15
|
+
s.require_path = 'lib'
|
16
|
+
s.email = 'justin dot w dot smith @t gmail.com'
|
17
|
+
s.files = PKG_FILES
|
18
|
+
s.homepage = 'https://rubygems.org/gems/dancing-links'
|
19
|
+
s.has_rdoc = true
|
20
|
+
s.rubyforge_project = 'sudoku-gtk'
|
21
|
+
s.description = 'An implementation of the "dancing links" algorithm to solve the "exact cover" problem.'
|
22
|
+
end
|
23
|
+
|
24
|
+
Rake::RDocTask.new do |rd|
|
25
|
+
rd.main = "README.rdoc"
|
26
|
+
rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
Gem::PackageTask.new(gem_spec) do |t|
|
31
|
+
t.need_zip = true
|
32
|
+
t.need_tar = true
|
33
|
+
end
|
34
|
+
|
data/lib/dancing_links.rb
CHANGED
@@ -19,56 +19,6 @@
|
|
19
19
|
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
20
|
|
21
21
|
|
22
|
-
=begin rdoc
|
23
|
-
|
24
|
-
This module provides an implementation of the "dancing links" algorhthm
|
25
|
-
to solve the "exact cover" problem.
|
26
|
-
|
27
|
-
The "exact cover" problem:
|
28
|
-
- Given a set of vectors containing 0's and 1's:
|
29
|
-
- Find a subset of these vectors that collectively contain one and only one 1 in each and every column.
|
30
|
-
|
31
|
-
For example the follwing set of vectors:
|
32
|
-
- A = [ 0, 1, 0]
|
33
|
-
- B = [ 1, 1, 0]
|
34
|
-
- C = [ 1, 0, 0]
|
35
|
-
- D = [ 0, 0, 1]
|
36
|
-
|
37
|
-
Has two solutions:
|
38
|
-
- A = [ 0, 1, 0]
|
39
|
-
- C = [ 1, 0, 0]
|
40
|
-
- D = [ 0, 0, 1]
|
41
|
-
|
42
|
-
and
|
43
|
-
- B = [ 1, 1, 0]
|
44
|
-
- D = [ 0, 0, 1]
|
45
|
-
|
46
|
-
A better description of the problem can be found here:
|
47
|
-
http://en.wikipedia.org/wiki/Exact_cover
|
48
|
-
|
49
|
-
The "dancing links" algorithm is a commonly used solution for this problem, and
|
50
|
-
was found by Donald Knuth. The algorithm involves the construction of a
|
51
|
-
sparse matrix containing nodes that are doubly-linked both horizontally and
|
52
|
-
vertically. The matrix itself simply facilitates the depth-first search
|
53
|
-
(aka backtracking) part of the algorithm.
|
54
|
-
|
55
|
-
The importance of the doubly-linked nodes are that they allow for quick
|
56
|
-
removal/restoration of rows/columns of nodes, which is exactly what a
|
57
|
-
backtracking algorithm for the "exact cover" problem needs.
|
58
|
-
|
59
|
-
horizontal removal:
|
60
|
-
- node.left.right = node.right
|
61
|
-
- node.right.left = node.left
|
62
|
-
|
63
|
-
horizontal restoration:
|
64
|
-
- node.left.right = node
|
65
|
-
- node.right.left = node
|
66
|
-
|
67
|
-
A better description of the algorithm can be found here:
|
68
|
-
http://en.wikipedia.org/wiki/Dancing_Links
|
69
|
-
|
70
|
-
=end
|
71
|
-
|
72
22
|
module DancingLinks
|
73
23
|
|
74
24
|
private
|
metadata
CHANGED
@@ -1,39 +1,48 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.8.10
|
3
|
-
specification_version: 1
|
1
|
+
--- !ruby/object:Gem::Specification
|
4
2
|
name: dancing-links
|
5
|
-
version: !ruby/object:Gem::Version
|
6
|
-
version:
|
7
|
-
|
8
|
-
summary: Implementation of the "Dancing Links" algorithm.
|
9
|
-
require_paths:
|
10
|
-
- lib
|
11
|
-
email: justin dot w dot smith at gmail dot com
|
12
|
-
homepage: http://rubyforge.org/projects/sudoku-gtk/
|
13
|
-
rubyforge_project:
|
14
|
-
description: Dancing-links is an implementation of the "Dancing Links" algorthm to solve the "Exact Cover" problem. Algorithm found by Donald Knuth.
|
15
|
-
autorequire: dancing_links
|
16
|
-
default_executable:
|
17
|
-
bindir: bin
|
18
|
-
has_rdoc: true
|
19
|
-
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
-
requirements:
|
21
|
-
-
|
22
|
-
- ">"
|
23
|
-
- !ruby/object:Gem::Version
|
24
|
-
version: 0.0.0
|
25
|
-
version:
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.1
|
5
|
+
prerelease:
|
26
6
|
platform: ruby
|
27
|
-
authors:
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
7
|
+
authors:
|
8
|
+
- Justin W Smith
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-27 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: An implementation of the "dancing links" algorithm to solve the "exact
|
15
|
+
cover" problem.
|
16
|
+
email: justin dot w dot smith @t gmail.com
|
35
17
|
executables: []
|
36
18
|
extensions: []
|
37
|
-
|
38
|
-
|
39
|
-
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- lib/dancing_links.rb
|
22
|
+
- Rakefile
|
23
|
+
- README.rdoc
|
24
|
+
homepage: https://rubygems.org/gems/dancing-links
|
25
|
+
licenses: []
|
26
|
+
post_install_message:
|
27
|
+
rdoc_options: []
|
28
|
+
require_paths:
|
29
|
+
- lib
|
30
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ! '>='
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ! '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
requirements: []
|
43
|
+
rubyforge_project: sudoku-gtk
|
44
|
+
rubygems_version: 1.8.11
|
45
|
+
signing_key:
|
46
|
+
specification_version: 3
|
47
|
+
summary: An implementation of "Dancing Links".
|
48
|
+
test_files: []
|
data/lib/array_combs_perms.rb
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
|
2
|
-
# Copyright (c) 2006 Justin W Smith
|
3
|
-
|
4
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
5
|
-
# software and associated documentation files (the "Software"), to deal in the Software
|
6
|
-
# without restriction, including without limitation the rights to use, copy, modify,
|
7
|
-
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
-
# permit persons to whom the Software is furnished to do so, subject to the following
|
9
|
-
# conditions:
|
10
|
-
|
11
|
-
# The above copyright notice and this permission notice shall be included in all copies
|
12
|
-
# or substantial portions of the Software.
|
13
|
-
|
14
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
15
|
-
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
16
|
-
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
17
|
-
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
18
|
-
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
19
|
-
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
|
-
|
21
|
-
class Array
|
22
|
-
def to_s
|
23
|
-
s = "["
|
24
|
-
each_index do |i|
|
25
|
-
s << " " + self[i].to_s
|
26
|
-
s << ", " unless (i == self.length-1)
|
27
|
-
end
|
28
|
-
s << "]"
|
29
|
-
end
|
30
|
-
|
31
|
-
def comb_helper head, tail, &block
|
32
|
-
if tail.length == 0
|
33
|
-
block.call(head)
|
34
|
-
else
|
35
|
-
tail.each_index do |i|
|
36
|
-
t = tail.clone
|
37
|
-
t.delete_at(i)
|
38
|
-
comb_helper head.clone << tail[i], t, &block
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def combinations &block
|
44
|
-
comb_helper [], self, &block
|
45
|
-
end
|
46
|
-
|
47
|
-
def permutations &block
|
48
|
-
perm_helper [self[0]], self[1...self.length], &block
|
49
|
-
end
|
50
|
-
|
51
|
-
def perm_helper head, tail, &block
|
52
|
-
block.call(head)
|
53
|
-
t = tail.clone
|
54
|
-
until t.empty?
|
55
|
-
val = t.pop
|
56
|
-
comb_helper head.clone << val, t, &block
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
data/test/tc_dancing_links.rb
DELETED
@@ -1,222 +0,0 @@
|
|
1
|
-
|
2
|
-
# Copyright (c) 2006 Justin W Smith
|
3
|
-
|
4
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
5
|
-
# software and associated documentation files (the "Software"), to deal in the Software
|
6
|
-
# without restriction, including without limitation the rights to use, copy, modify,
|
7
|
-
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
-
# permit persons to whom the Software is furnished to do so, subject to the following
|
9
|
-
# conditions:
|
10
|
-
|
11
|
-
# The above copyright notice and this permission notice shall be included in all copies
|
12
|
-
# or substantial portions of the Software.
|
13
|
-
|
14
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
15
|
-
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
16
|
-
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
17
|
-
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
18
|
-
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
19
|
-
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
|
-
|
21
|
-
|
22
|
-
require 'test/unit'
|
23
|
-
require 'lib/dancing_links'
|
24
|
-
|
25
|
-
class Array
|
26
|
-
def to_s
|
27
|
-
s = "["
|
28
|
-
each_index do |i|
|
29
|
-
s << " " + self[i].to_s
|
30
|
-
s << ", " unless (i == self.length-1)
|
31
|
-
end
|
32
|
-
s << "]"
|
33
|
-
end
|
34
|
-
|
35
|
-
def comb_helper head, tail, &block
|
36
|
-
if tail.length == 0
|
37
|
-
block.call(head)
|
38
|
-
else
|
39
|
-
tail.each_index do |i|
|
40
|
-
t = tail.clone
|
41
|
-
t.delete_at(i)
|
42
|
-
comb_helper head.clone << tail[i], t, &block
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def combinations &block
|
48
|
-
comb_helper [], self, &block
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
class TC_DancingLinks < Test::Unit::TestCase
|
53
|
-
include DancingLinks
|
54
|
-
|
55
|
-
def setup
|
56
|
-
@a1 = [ [1, 0, 1], [0, 0, 1], [1, 1, 0], [ 1, 0, 0] ]
|
57
|
-
@b1 = [ [ true, false, true],
|
58
|
-
[false, false, true],
|
59
|
-
[true, true, false],
|
60
|
-
[true, false, false] ]
|
61
|
-
@matrix1 = SparseMatrix.new convert_rows_fixnum_to_boolean(@a1)
|
62
|
-
@s1 = [ [ 0, 0, 1], [ 1, 1, 0] ]
|
63
|
-
|
64
|
-
@a2 = [ [1, 0, 1], [1, 1, 0], [0, 1, 1], [ 0, 0, 0] ]
|
65
|
-
@e2 = [ [0, 0, 1] ]
|
66
|
-
@matrix2 = SparseMatrix.new convert_rows_fixnum_to_boolean(@a2)
|
67
|
-
@s2 = [ [0, 0, 1], [ 1, 1, 0] ]
|
68
|
-
|
69
|
-
@a3 = [ [1, 0, 1], [1, 1, 0], [0, 1, 1], [ 1, 1, 1] ]
|
70
|
-
@matrix3 = SparseMatrix.new convert_rows_fixnum_to_boolean(@a3)
|
71
|
-
@s3 = [[1, 1, 1]]
|
72
|
-
|
73
|
-
@a4 = [ [1, 0, 1], [1, 1, 0], [0, 1, 1], [ 0, 1, 0] ]
|
74
|
-
@matrix4 = SparseMatrix.new convert_rows_fixnum_to_boolean(@a4)
|
75
|
-
@s4 = [[1, 0, 1], [0, 1, 0]]
|
76
|
-
|
77
|
-
@a5 = [ [1, 0, 1], [1, 1, 0], [1, 1, 1], [ 0, 1, 1] ]
|
78
|
-
@matrix5 = SparseMatrix.new convert_rows_fixnum_to_boolean(@a4)
|
79
|
-
@s5 = [[1, 1, 1]]
|
80
|
-
|
81
|
-
@a6 = [ [1, 0, 1], [1, 0, 0], [1, 1, 1], [ 0, 1, 1], [1, 1, 0] ]
|
82
|
-
|
83
|
-
@a7 = [ [0, 0, 1], [ 0, 1, 0], [0, 1, 1], [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1] ]
|
84
|
-
@s7 = [
|
85
|
-
[ [ 1, 1, 1] ],
|
86
|
-
[ [ 0, 1, 1], [ 1, 0, 0 ] ].sort,
|
87
|
-
[ [ 1, 0, 1], [ 0, 1, 0 ] ].sort,
|
88
|
-
[ [ 1, 1, 0], [ 0, 0, 1] ].sort,
|
89
|
-
[ [ 0, 0, 1], [0, 1, 0], [1, 0, 0] ].sort ]
|
90
|
-
end
|
91
|
-
|
92
|
-
def test_convert_rows
|
93
|
-
assert_equal(@a1, convert_rows_boolean_to_fixnum(@b1) )
|
94
|
-
assert_equal(@b1, convert_rows_fixnum_to_boolean(@a1) )
|
95
|
-
end
|
96
|
-
|
97
|
-
def test_sparse_matrix
|
98
|
-
root = @matrix1.root
|
99
|
-
assert_equal(3, root.count)
|
100
|
-
assert_equal(3, root.right.count)
|
101
|
-
assert_equal(1, root.right.right.count)
|
102
|
-
assert_equal(2, root.right.right.right.count)
|
103
|
-
assert_equal(root.right.up.left, root.right.up)
|
104
|
-
assert_equal(root.left.up.left, root.right.right.right.down.down)
|
105
|
-
assert_equal(root.right.down.header, root.right)
|
106
|
-
assert_equal(root.left.up.header, root.left)
|
107
|
-
assert_equal(root.right.right.right.right, root)
|
108
|
-
assert_equal(root.left.left.left.left, root)
|
109
|
-
|
110
|
-
assert_equal(0, root.left.down.row_num)
|
111
|
-
assert_equal(1, root.left.down.down.row_num)
|
112
|
-
assert_equal(2, root.right.right.down.row_num)
|
113
|
-
assert_equal(3, root.right.up.row_num)
|
114
|
-
|
115
|
-
assert_equal(0, root.right.index)
|
116
|
-
assert_equal(3, root.right.count)
|
117
|
-
assert_equal(1, root.right.right.index)
|
118
|
-
assert_equal(1, root.right.right.count)
|
119
|
-
assert_equal(2, root.right.right.right.index)
|
120
|
-
assert_equal(2, root.right.right.right.count)
|
121
|
-
|
122
|
-
end
|
123
|
-
|
124
|
-
def test_remove_rows_for_header
|
125
|
-
root = @matrix1.root
|
126
|
-
remove_rows_for_header root.right
|
127
|
-
assert_equal( 0, root.right.count)
|
128
|
-
assert_equal( 0, root.right.right.count)
|
129
|
-
assert_equal( 1, root.right.right.right.count)
|
130
|
-
assert_equal( root.right.right.right, root.left)
|
131
|
-
assert_equal( root.left.down, root.right.right.right.up)
|
132
|
-
assert_equal( 1, root.left.down.row_num)
|
133
|
-
end
|
134
|
-
|
135
|
-
def test_restore_rows_for_header
|
136
|
-
root = @matrix1.root
|
137
|
-
restore_rows_for_header( remove_rows_for_header( root.right))
|
138
|
-
test_sparse_matrix
|
139
|
-
end
|
140
|
-
|
141
|
-
def test_select_row
|
142
|
-
root = @matrix1.root
|
143
|
-
header_stk, row_stk_stk = select_row root.right.right.down
|
144
|
-
|
145
|
-
assert_equal( 1, root.count)
|
146
|
-
assert_equal( 1, root.right.count)
|
147
|
-
assert_equal( 2, root.right.index )
|
148
|
-
assert_equal( root.right.down, root.left.down)
|
149
|
-
assert_equal( root.right.down.down, root.left)
|
150
|
-
assert_equal( root.right.down.down, root.left)
|
151
|
-
|
152
|
-
end
|
153
|
-
|
154
|
-
def test_restore_selected_row
|
155
|
-
|
156
|
-
root = @matrix1.root
|
157
|
-
restore_selected_row( *select_row( root.right.right.down))
|
158
|
-
test_sparse_matrix
|
159
|
-
restore_selected_row( *select_row( root.right.down))
|
160
|
-
test_sparse_matrix
|
161
|
-
restore_selected_row( *select_row( root.left.down))
|
162
|
-
test_sparse_matrix
|
163
|
-
restore_selected_row( *select_row( root.left.up))
|
164
|
-
test_sparse_matrix
|
165
|
-
restore_selected_row( *select_row( root.right.up))
|
166
|
-
test_sparse_matrix
|
167
|
-
restore_selected_row( *select_row( root.left.up))
|
168
|
-
test_sparse_matrix
|
169
|
-
|
170
|
-
header_stk, row_stk_stk = select_row( root.right.right.down)
|
171
|
-
restore_selected_row( *select_row( root.right.down) )
|
172
|
-
restore_selected_row( header_stk, row_stk_stk)
|
173
|
-
test_sparse_matrix
|
174
|
-
|
175
|
-
end
|
176
|
-
|
177
|
-
def test_min_column
|
178
|
-
root = @matrix1.root
|
179
|
-
header = min_column root
|
180
|
-
assert_equal( root.right.right, header)
|
181
|
-
end
|
182
|
-
|
183
|
-
def test_solve_exact_cover
|
184
|
-
s = convert_rows_boolean_to_fixnum(solve_exact_cover( @b1))
|
185
|
-
assert_equal(@s1.sort, s.sort)
|
186
|
-
|
187
|
-
s = solve_exact_cover( convert_rows_fixnum_to_boolean(@a2))
|
188
|
-
assert_equal(0, s)
|
189
|
-
|
190
|
-
s = convert_rows_boolean_to_fixnum(solve_exact_cover( convert_rows_fixnum_to_boolean(@a2), convert_rows_fixnum_to_boolean(@e2)))
|
191
|
-
assert_equal(@s2.sort, s.sort)
|
192
|
-
|
193
|
-
s = convert_rows_boolean_to_fixnum(solve_exact_cover( convert_rows_fixnum_to_boolean(@a3)))
|
194
|
-
assert_equal(@s3.sort, s.sort)
|
195
|
-
|
196
|
-
s = convert_rows_boolean_to_fixnum(solve_exact_cover( convert_rows_fixnum_to_boolean(@a4)))
|
197
|
-
assert_equal(@s4.sort, s.sort)
|
198
|
-
|
199
|
-
s = convert_rows_boolean_to_fixnum(solve_exact_cover( convert_rows_fixnum_to_boolean(@a5)))
|
200
|
-
assert_equal(@s5.sort, s.sort)
|
201
|
-
|
202
|
-
s = solve_exact_cover( convert_rows_fixnum_to_boolean(@a6)){false}
|
203
|
-
assert_equal(2, s)
|
204
|
-
|
205
|
-
end
|
206
|
-
|
207
|
-
def test_solve_exact_cover2
|
208
|
-
|
209
|
-
@a7.combinations do |comb|
|
210
|
-
s = @s7.clone
|
211
|
-
solve_exact_cover(convert_rows_fixnum_to_boolean(comb)) do |result|
|
212
|
-
result = convert_rows_boolean_to_fixnum( result ).sort!
|
213
|
-
assert( s.member?( result ), "\ncomb: #{comb.to_s}\nresult: #{result}\nsolutions left: #{s.to_s}")
|
214
|
-
s.delete result
|
215
|
-
false
|
216
|
-
end
|
217
|
-
assert_equal( [], s)
|
218
|
-
end
|
219
|
-
|
220
|
-
end
|
221
|
-
|
222
|
-
end
|