nonograms 0.1.1 → 0.2.0

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 CHANGED
@@ -54,6 +54,24 @@ 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::Solver.new(vertical, horizontal)
57
+ > @nonograms = Nonograms.new(horizontal, vertical)
58
58
  > @nonograms.solve #=> ["01000"+"01101"+"10000"+"01001", ...]
59
59
 
60
+
61
+ Display result on the console
62
+
63
+ > @nonograms.display
64
+ #=> result: 0
65
+ #=>
66
+ #=> ■
67
+ #=> ■ ■ ■
68
+ #=> ■
69
+ #=> ■ ■
70
+ #=>
71
+ #=> result: 1
72
+ #=>
73
+ #=> ■
74
+ #=> ■ ■ ■
75
+ #=> ■
76
+ #=> ■ ■
77
+
data/lib/nonograms.rb CHANGED
@@ -1,3 +1,108 @@
1
1
  # encoding: utf-8
2
2
  require "nonograms/version"
3
- require "nonograms/solver"
3
+ require "nonograms/display"
4
+ require "nonograms/checker"
5
+
6
+ # class can solve the puzzle game Nonograms
7
+ class Nonograms
8
+
9
+ def initialize(horizontal, vertical)
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
+ # display the result on console
26
+ def display
27
+ Nonograms::Display.new(@results, @amount_row, @amount_column)
28
+ end
29
+
30
+ # count amount values '1' in vector
31
+ # for example:
32
+ # * vector : [0, 1, 1, 0, 0, 1, 0]
33
+ # * return: [2, 1]
34
+ def count_vector(vector)
35
+ vector.join("").scan(/[1]+/).map{|element| element.length}
36
+ end
37
+
38
+ # count amount values '1' in vertical vector
39
+ def count_vertical(column)
40
+ vertical_vector = @puzzle[0...@amount_row].map{|vector| vector[column]}
41
+ count_vector(vertical_vector)
42
+ end
43
+
44
+ # count amount values '1' in vertical vector
45
+ def count_horizontal(row)
46
+ horizontal_vector = @puzzle[row][0...@amount_column]
47
+ count_vector(horizontal_vector)
48
+ end
49
+
50
+ def vertical_acceptable?(row, column)
51
+ unless row == @amount_row-1
52
+ vector_acceptable?( @vertical[column], count_vertical(column) )
53
+ else
54
+ return ( @vertical[column] == count_vertical(column) )
55
+ end
56
+ end
57
+
58
+ def horizontal_acceptable?(row, column)
59
+ unless column == @amount_column-1
60
+ vector_acceptable?( @horizontal[row], count_horizontal(row) )
61
+ else
62
+ return ( @horizontal[row] == count_horizontal(row))
63
+ end
64
+ end
65
+
66
+ def vector_acceptable?(origin, piece)
67
+ return false if piece.length > origin.length
68
+ piece.each_with_index do |value, index|
69
+ if index == piece.length-1
70
+ return false unless origin[index] >= piece[index]
71
+ else
72
+ return false unless origin[index] == piece[index]
73
+ end
74
+ end
75
+ return true
76
+ end
77
+
78
+ # get the matrix with cells values zero
79
+ def empty_puzzle
80
+ result = []
81
+ @amount_row.times do |index|
82
+ result << [0]*@amount_column
83
+ end
84
+ result
85
+ end
86
+
87
+ private
88
+
89
+ # run recursion from fixed position row and column if @puzzle is acceptable
90
+ def run_recursion(row = 0, column = 0)
91
+ return unless vertical_acceptable?(row, column) and horizontal_acceptable?(row, column)
92
+ if row == @amount_row-1 and column == @amount_column-1
93
+ @results << Marshal.load(Marshal.dump(@puzzle)).flatten.join("")
94
+ return nil
95
+ end
96
+ next_cell_set(0, row, column)
97
+ next_cell_set(1, row, column)
98
+ end
99
+
100
+ def next_cell_set(value, row, column)
101
+ new_row = (row*@amount_column + column + 1) / @amount_column
102
+ new_column = (row*@amount_column + column + 1) % @amount_column
103
+ @puzzle[new_row][new_column] = value
104
+ run_recursion(new_row, new_column)
105
+ @puzzle[new_row][new_column] = 0
106
+ end
107
+
108
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+
3
+ class Nonograms
4
+ class Checker
5
+
6
+ def initialize(vertical, horizontal)
7
+ @vertical = vertical
8
+ @horizontal = horizontal
9
+ end
10
+
11
+ def properly_data_entered?
12
+ @vertical.flatten.inject(&:+) == @horizontal.flatten.inject(&:+)
13
+ end
14
+
15
+ # TODO
16
+ end
17
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ class Nonograms
4
+ class Display
5
+
6
+ def initialize(results, amount_row, amount_column)
7
+ @results = results
8
+ @amount_row = amount_row
9
+ @amount_column = amount_column
10
+ show_results(results)
11
+ end
12
+
13
+ def show_results(results)
14
+ results.each_with_index do |result, index|
15
+ puts "result: " + index.to_s
16
+ show_result(result)
17
+ end
18
+ end
19
+
20
+ def show_result(result)
21
+ result.split("").each_with_index do |value, index|
22
+ print "\n" if index % @amount_column == 0
23
+ print "■ " if value == "1"
24
+ print " " if value == "0"
25
+ end
26
+ print "\n\n"
27
+ end
28
+ end
29
+ end
@@ -1,3 +1,3 @@
1
- module Nonograms
2
- VERSION = "0.1.1"
1
+ class Nonograms
2
+ VERSION = "0.2.0"
3
3
  end
data/nonograms.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
  require File.expand_path('../lib/nonograms/version', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |gem|
5
- gem.authors = ["Michał Szyma"]
5
+ gem.authors = ["Michal Szyma"]
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.}
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+ require 'nonograms'
3
+
4
+ describe Nonograms::Checker do
5
+
6
+ it "should return true" do
7
+ vertical = [[2, 1], [1]]
8
+ horizontal = [[1], [2], [], [1]]
9
+ Nonograms::Checker.new(vertical, horizontal).properly_data_entered?.should be_true
10
+ end
11
+
12
+ it "should return false" do
13
+ vertical = [[2, 1], [1]]
14
+ horizontal = [[1], [3], [], [1]]
15
+ Nonograms::Checker.new(vertical, horizontal).properly_data_entered?.should be_false
16
+ end
17
+
18
+ end
@@ -5,11 +5,30 @@ 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::Solver.new(vertical, horizontal)
8
+ @nonograms = Nonograms.new(horizontal, vertical)
9
9
  end
10
10
 
11
11
  it "should properly solve the nonograms" do
12
12
  @nonograms.solve.should include("01000"+"01101"+"10000"+"01001")
13
13
  end
14
14
 
15
+ it "should properly count amount of numbers 1 in vector" do
16
+ vector = [0, 0, 1, 1, 1, 0, 1]
17
+ @nonograms.count_vector(vector).should eql([3, 1])
18
+ end
19
+
20
+ it "for vectors acceptable" do
21
+ origin = [3, 1, 2]
22
+ @nonograms.vector_acceptable?(origin, [3, 1]).should be_true
23
+ @nonograms.vector_acceptable?(origin, [3, 1, 2]).should be_true
24
+ @nonograms.vector_acceptable?(origin, [3, 1, 1]).should be_true
25
+ @nonograms.vector_acceptable?(origin, []).should be_true
26
+ end
27
+
28
+ it "for vectors don't acceptable" do
29
+ origin = [3, 1, 2]
30
+ @nonograms.vector_acceptable?(origin, [4, 1]).should be_false
31
+ @nonograms.vector_acceptable?(origin, [3, 1, 2, 4]).should be_false
32
+ @nonograms.vector_acceptable?(origin, [3, 1, 3]).should be_false
33
+ end
15
34
  end
metadata CHANGED
@@ -1,11 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nonograms
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
8
- - Michał Szyma
8
+ - Michal Szyma
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
@@ -40,9 +40,11 @@ files:
40
40
  - README.md
41
41
  - Rakefile
42
42
  - lib/nonograms.rb
43
- - lib/nonograms/solver.rb
43
+ - lib/nonograms/checker.rb
44
+ - lib/nonograms/display.rb
44
45
  - lib/nonograms/version.rb
45
46
  - nonograms.gemspec
47
+ - spec/checker_spec.rb
46
48
  - spec/nonograms_spec.rb
47
49
  homepage: https://github.com/raglub/nonograms
48
50
  licenses: []
@@ -69,4 +71,5 @@ signing_key:
69
71
  specification_version: 3
70
72
  summary: Solve Nonograms.
71
73
  test_files:
74
+ - spec/checker_spec.rb
72
75
  - spec/nonograms_spec.rb
@@ -1,104 +0,0 @@
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