nonograms 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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