nonograms 0.1.0 → 0.1.1
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.
- data/README.md +2 -3
- data/lib/nonograms.rb +1 -98
- data/lib/nonograms/solver.rb +104 -0
- data/lib/nonograms/version.rb +2 -2
- data/nonograms.gemspec +1 -1
- data/spec/nonograms_spec.rb +3 -3
- metadata +3 -2
data/README.md
CHANGED
@@ -54,7 +54,6 @@ You can solve this example when you write the code below
|
|
54
54
|
|
55
55
|
> vertical = [[1], [2, 1], [1], [], [1, 1]]
|
56
56
|
> horizontal = [[1], [2, 1], [1], [1, 1]]
|
57
|
-
> @nonograms = Nonograms.new(vertical, horizontal)
|
58
|
-
> @nonograms.solve
|
59
|
-
> @nonograms.results #=> ["01000"+"01101"+"10000"+"01001", ...]
|
57
|
+
> @nonograms = Nonograms::Solver.new(vertical, horizontal)
|
58
|
+
> @nonograms.solve #=> ["01000"+"01101"+"10000"+"01001", ...]
|
60
59
|
|
data/lib/nonograms.rb
CHANGED
@@ -1,100 +1,3 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require "nonograms/version"
|
3
|
-
|
4
|
-
# class can solve the puzzle game Nonograms
|
5
|
-
class Nonograms
|
6
|
-
|
7
|
-
attr_reader :results
|
8
|
-
|
9
|
-
def initialize(vertical, horizontal)
|
10
|
-
@vertical = vertical
|
11
|
-
@horizontal = horizontal
|
12
|
-
@amount_row = horizontal.length
|
13
|
-
@amount_column = vertical.length
|
14
|
-
@puzzle = []
|
15
|
-
@amount_row.times do |index|
|
16
|
-
@puzzle << [0]*@amount_column
|
17
|
-
end
|
18
|
-
@results = []
|
19
|
-
end
|
20
|
-
|
21
|
-
def solve(row = 0, column = 0)
|
22
|
-
if vertical_acceptable?(row, column) and horizontal_acceptable?(row, column)
|
23
|
-
if row == @amount_row-1 and column == @amount_column-1
|
24
|
-
@results << Marshal.load(Marshal.dump(@puzzle)).flatten.join("")
|
25
|
-
return @amount_column
|
26
|
-
end
|
27
|
-
next_cell_set(0, row, column)
|
28
|
-
next_cell_set(1, row, column)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def next_cell_set(value, row, column)
|
35
|
-
new_row = (row*@amount_column + column + 1) / @amount_column
|
36
|
-
new_column = (row*@amount_column + column + 1) % @amount_column
|
37
|
-
@puzzle[new_row][new_column] = value
|
38
|
-
solve(new_row, new_column)
|
39
|
-
@puzzle[new_row][new_column] = 0
|
40
|
-
end
|
41
|
-
|
42
|
-
# count values '1' in vertical
|
43
|
-
def count_vertical(column)
|
44
|
-
result, counter = [], 0
|
45
|
-
@amount_row.times do |index|
|
46
|
-
if @puzzle[index][column] == 1
|
47
|
-
counter += 1
|
48
|
-
else
|
49
|
-
result << counter unless counter == 0
|
50
|
-
counter = 0
|
51
|
-
end
|
52
|
-
result << counter if index == @amount_row-1 and not counter == 0
|
53
|
-
end
|
54
|
-
result
|
55
|
-
end
|
56
|
-
|
57
|
-
# count values '1' in horizontal
|
58
|
-
def count_horizontal(row)
|
59
|
-
result, counter = [], 0
|
60
|
-
@amount_column.times do |index|
|
61
|
-
if @puzzle[row][index] == 1
|
62
|
-
counter += 1
|
63
|
-
else
|
64
|
-
result << counter unless counter == 0
|
65
|
-
counter = 0
|
66
|
-
end
|
67
|
-
result << counter if index == @amount_column-1 and not counter == 0
|
68
|
-
end
|
69
|
-
result
|
70
|
-
end
|
71
|
-
|
72
|
-
def vertical_acceptable?(row, column)
|
73
|
-
unless row == @amount_row-1
|
74
|
-
vector_acceptable?( @vertical[column], count_vertical(column) )
|
75
|
-
else
|
76
|
-
return ( @vertical[column] == count_vertical(column) )
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def horizontal_acceptable?(row, column)
|
81
|
-
unless column == @amount_column-1
|
82
|
-
vector_acceptable?( @horizontal[row], count_horizontal(row) )
|
83
|
-
else
|
84
|
-
return ( @horizontal[row] == count_horizontal(row))
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
def vector_acceptable?(origin, piece)
|
89
|
-
return false if piece.length > origin.length
|
90
|
-
piece.each_with_index do |value, index|
|
91
|
-
if index == piece.length-1
|
92
|
-
return false unless origin[index] >= piece[index]
|
93
|
-
else
|
94
|
-
return false unless origin[index] == piece[index]
|
95
|
-
end
|
96
|
-
end
|
97
|
-
return true
|
98
|
-
end
|
99
|
-
|
100
|
-
end
|
3
|
+
require "nonograms/solver"
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Nonograms
|
3
|
+
|
4
|
+
# class can solve the puzzle game Nonograms
|
5
|
+
class Solver
|
6
|
+
|
7
|
+
attr_reader :results
|
8
|
+
|
9
|
+
def initialize(vertical, horizontal)
|
10
|
+
@vertical = vertical
|
11
|
+
@horizontal = horizontal
|
12
|
+
@amount_row = horizontal.length
|
13
|
+
@amount_column = vertical.length
|
14
|
+
@puzzle = empty_puzzle
|
15
|
+
@results = []
|
16
|
+
end
|
17
|
+
|
18
|
+
# solve the nonograms
|
19
|
+
def solve
|
20
|
+
return @results unless @results.empty?
|
21
|
+
run_recursion
|
22
|
+
@results
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# get the matrix with cells values zero
|
28
|
+
def empty_puzzle
|
29
|
+
result = []
|
30
|
+
@amount_row.times do |index|
|
31
|
+
result << [0]*@amount_column
|
32
|
+
end
|
33
|
+
result
|
34
|
+
end
|
35
|
+
|
36
|
+
# run recursion from fixed position row and column if @puzzle is acceptable
|
37
|
+
def run_recursion(row = 0, column = 0)
|
38
|
+
return unless vertical_acceptable?(row, column) and horizontal_acceptable?(row, column)
|
39
|
+
if row == @amount_row-1 and column == @amount_column-1
|
40
|
+
@results << Marshal.load(Marshal.dump(@puzzle)).flatten.join("")
|
41
|
+
return nil
|
42
|
+
end
|
43
|
+
next_cell_set(0, row, column)
|
44
|
+
next_cell_set(1, row, column)
|
45
|
+
end
|
46
|
+
|
47
|
+
def next_cell_set(value, row, column)
|
48
|
+
new_row = (row*@amount_column + column + 1) / @amount_column
|
49
|
+
new_column = (row*@amount_column + column + 1) % @amount_column
|
50
|
+
@puzzle[new_row][new_column] = value
|
51
|
+
run_recursion(new_row, new_column)
|
52
|
+
@puzzle[new_row][new_column] = 0
|
53
|
+
end
|
54
|
+
|
55
|
+
# count amount values '1' in vector
|
56
|
+
# for example:
|
57
|
+
# * vector : [0, 1, 1, 0, 0, 1, 0]
|
58
|
+
# * return: [2, 1]
|
59
|
+
def count_vector(vector)
|
60
|
+
vector.join("").scan(/[1]+/).map{|element| element.length}
|
61
|
+
end
|
62
|
+
|
63
|
+
# count amount values '1' in vertical vector
|
64
|
+
def count_vertical(column)
|
65
|
+
vertical_vector = @puzzle[0...@amount_row].map{|vector| vector[column]}
|
66
|
+
count_vector(vertical_vector)
|
67
|
+
end
|
68
|
+
|
69
|
+
# count amount values '1' in vertical vector
|
70
|
+
def count_horizontal(row)
|
71
|
+
horizontal_vector = @puzzle[row][0...@amount_column]
|
72
|
+
count_vector(horizontal_vector)
|
73
|
+
end
|
74
|
+
|
75
|
+
def vertical_acceptable?(row, column)
|
76
|
+
unless row == @amount_row-1
|
77
|
+
vector_acceptable?( @vertical[column], count_vertical(column) )
|
78
|
+
else
|
79
|
+
return ( @vertical[column] == count_vertical(column) )
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def horizontal_acceptable?(row, column)
|
84
|
+
unless column == @amount_column-1
|
85
|
+
vector_acceptable?( @horizontal[row], count_horizontal(row) )
|
86
|
+
else
|
87
|
+
return ( @horizontal[row] == count_horizontal(row))
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def vector_acceptable?(origin, piece)
|
92
|
+
return false if piece.length > origin.length
|
93
|
+
piece.each_with_index do |value, index|
|
94
|
+
if index == piece.length-1
|
95
|
+
return false unless origin[index] >= piece[index]
|
96
|
+
else
|
97
|
+
return false unless origin[index] == piece[index]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
return true
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
data/lib/nonograms/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION = "0.1.
|
1
|
+
module Nonograms
|
2
|
+
VERSION = "0.1.1"
|
3
3
|
end
|
data/nonograms.gemspec
CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |gem|
|
|
6
6
|
gem.email = ["raglub.ruby@gmail.com"]
|
7
7
|
gem.description = %q{solve the puzzle game nonograms.}
|
8
8
|
gem.summary = %q{Solve Nonograms.}
|
9
|
-
gem.date = "2012-07-
|
9
|
+
gem.date = "2012-07-07"
|
10
10
|
gem.homepage = "https://github.com/raglub/nonograms"
|
11
11
|
|
12
12
|
gem.files = `git ls-files`.split($\)
|
data/spec/nonograms_spec.rb
CHANGED
@@ -5,11 +5,11 @@ describe "Nonograms" do
|
|
5
5
|
before(:each) do
|
6
6
|
vertical = [[1], [2, 1], [1], [], [1, 1]]
|
7
7
|
horizontal = [[1], [2, 1], [1], [1, 1]]
|
8
|
-
@nonograms = Nonograms.new(vertical, horizontal)
|
8
|
+
@nonograms = Nonograms::Solver.new(vertical, horizontal)
|
9
9
|
end
|
10
10
|
|
11
11
|
it "should properly solve the nonograms" do
|
12
|
-
@nonograms.solve
|
13
|
-
@nonograms.results.should include("01000"+"01101"+"10000"+"01001")
|
12
|
+
@nonograms.solve.should include("01000"+"01101"+"10000"+"01001")
|
14
13
|
end
|
14
|
+
|
15
15
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nonograms
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-07-
|
12
|
+
date: 2012-07-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -40,6 +40,7 @@ files:
|
|
40
40
|
- README.md
|
41
41
|
- Rakefile
|
42
42
|
- lib/nonograms.rb
|
43
|
+
- lib/nonograms/solver.rb
|
43
44
|
- lib/nonograms/version.rb
|
44
45
|
- nonograms.gemspec
|
45
46
|
- spec/nonograms_spec.rb
|