nonograms 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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
 
@@ -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
@@ -1,3 +1,3 @@
1
- class Nonograms
2
- VERSION = "0.1.0"
1
+ module Nonograms
2
+ VERSION = "0.1.1"
3
3
  end
@@ -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-03"
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($\)
@@ -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.0
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-03 00:00:00.000000000 Z
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