grid_struct 0.0.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.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/Guardfile +17 -0
- data/LICENSE.txt +22 -0
- data/README.md +326 -0
- data/Rakefile +7 -0
- data/grid_struct.gemspec +26 -0
- data/lib/grid_struct/selector.rb +38 -0
- data/lib/grid_struct/version.rb +3 -0
- data/lib/grid_struct.rb +186 -0
- data/spec/lib/grid_struct/selector_spec.rb +81 -0
- data/spec/lib/grid_struct_spec.rb +296 -0
- data/spec/spec_helper.rb +7 -0
- metadata +131 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8123cc6cecee6f31395c03f4f6bb71d097ac4fd1
|
4
|
+
data.tar.gz: 8a620e7b2af1da9daa5bdb595c388c535a14c16d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 64a7448a8fb6b4273d5dcf61d7625f523c5db7b9b97cc26cf66b8580a4df4c2cc2d7a28f4e785c82edd811ed305106be57c2768b1da0a909925dd600dfdae75a
|
7
|
+
data.tar.gz: 286fe7c82704872ecc924f2c414f5b0089b607623e4c2fecb79ee200ac547f3f7f7dfd3cde17e5c5755a9f5bd541f66f6df665f12d0b9288cc7fa7b34f811141
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
# Note: The cmd option is now required due to the increasing number of ways
|
5
|
+
# rspec may be run, below are examples of the most common uses.
|
6
|
+
# * bundler: 'bundle exec rspec'
|
7
|
+
# * bundler binstubs: 'bin/rspec'
|
8
|
+
# * spring: 'bin/rsspec' (This will use spring if running and you have
|
9
|
+
# installed the spring binstubs per the docs)
|
10
|
+
# * zeus: 'zeus rspec' (requires the server to be started separetly)
|
11
|
+
# * 'just' rspec: 'rspec'
|
12
|
+
guard :rspec, cmd: 'bundle exec rspec' do
|
13
|
+
watch(%r{^spec/.+_spec\.rb$})
|
14
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
15
|
+
watch('spec/spec_helper.rb') { "spec" }
|
16
|
+
end
|
17
|
+
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Samuel Molinari
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,326 @@
|
|
1
|
+
# GridStruct
|
2
|
+
|
3
|
+
Manipulate grid like structure in Ruby.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'grid_struct'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install grid_struct
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
### Create a GridStruct
|
22
|
+
|
23
|
+
In order to create a grid, you have to pass a 2 arguments:
|
24
|
+
|
25
|
+
- ``rows``: the number of rows your grid has (the height of the grid)
|
26
|
+
- ``columns``: the number columns your grid has (the width of the grid)
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
rows = 9
|
30
|
+
columns = 5
|
31
|
+
|
32
|
+
# Create a grid of size 5x9
|
33
|
+
grid = GridStruct.new(rows, columns)
|
34
|
+
|
35
|
+
grid.size # => 45
|
36
|
+
grid.columns # => 5
|
37
|
+
grid.rows # => 9
|
38
|
+
```
|
39
|
+
|
40
|
+
It is possible to initialize the array with pre-set values.
|
41
|
+
The 3rd argument must be an array.
|
42
|
+
|
43
|
+
If we want to initialize the following grid:
|
44
|
+
|
45
|
+
```
|
46
|
+
+---+---+---+
|
47
|
+
| X | O | O |
|
48
|
+
+---+---+---+
|
49
|
+
| X | x | O |
|
50
|
+
+---+---+---+
|
51
|
+
| O | X | O |
|
52
|
+
+---+---+---+
|
53
|
+
|
54
|
+
```
|
55
|
+
|
56
|
+
Use the following array structure:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
# +-----------+-----------+-----------+
|
60
|
+
# | ROW 0 | ROW 1 | ROW 2 |
|
61
|
+
# +---------+-----------+-----------+-----------+
|
62
|
+
# | COLUMNS | 0 | 1 | 2 | 0 | 1 | 2 | 0 | 1 | 2 |
|
63
|
+
grid_data = ['X','O','O','X','X','O','O','X','O']
|
64
|
+
|
65
|
+
tic_tac_toe = GridStruct.new(3, 3, grid_data)
|
66
|
+
```
|
67
|
+
|
68
|
+
``GridStruct`` actually store your values extactly the same way, in a 1-dimentional array.
|
69
|
+
|
70
|
+
### Basics
|
71
|
+
|
72
|
+
Now you know how to create grids, it's time to learn how to use our new data structure.
|
73
|
+
|
74
|
+
#### Read the data store
|
75
|
+
|
76
|
+
As mentionned above, your data are stored in a 1-dimentional array.
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
tic_tac_toe.store # => ["X","O","O","X","X","O","O","X","O"]
|
80
|
+
|
81
|
+
GridStruct.new(9,9).store # => []
|
82
|
+
```
|
83
|
+
|
84
|
+
As you can see, the ``store`` always starts as an empty array unless you decide to pre-fill the grid.
|
85
|
+
|
86
|
+
#### Set value
|
87
|
+
|
88
|
+
To set a value, pass the row and column you want to fill, and a block that will return the value
|
89
|
+
|
90
|
+
```
|
91
|
+
GridStruct#set(row, column) { value }
|
92
|
+
```
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
sudoku_grid = GridStruct.new(9,9)
|
96
|
+
|
97
|
+
sudoku_grid.set(0,0) { 'Hello World' }
|
98
|
+
sudoku_grid.store # => ["Hello World"]
|
99
|
+
|
100
|
+
sudoku_grid.set(1,0) { 'Row: 1, Col: 0' }
|
101
|
+
sudoku_grid.store # => ["Hello World",nil,nil,nil,nil,nil,nil,nil,"Row: 1, Col: 0"]
|
102
|
+
```
|
103
|
+
|
104
|
+
#### Get value
|
105
|
+
|
106
|
+
To get a value at a specific coordinate, use th ``get`` method.
|
107
|
+
|
108
|
+
```
|
109
|
+
GridStruct#get(row, column) # => value
|
110
|
+
```
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
sudoku_grid.get(1,0) # => "Row: 1, Col: 0"
|
114
|
+
```
|
115
|
+
|
116
|
+
### Iterate
|
117
|
+
|
118
|
+
You can iterate through the grid using the each method
|
119
|
+
|
120
|
+
```
|
121
|
+
GridStruct#each { |value, row, column| # Do something }
|
122
|
+
```
|
123
|
+
|
124
|
+
### Mass update
|
125
|
+
|
126
|
+
#### Grid
|
127
|
+
|
128
|
+
Incase you need to update each element within the grid, use the ``map!`` method
|
129
|
+
|
130
|
+
```
|
131
|
+
GridStruct#map! { |value, row, column| # Return new value }
|
132
|
+
```
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
grid = GridStruct.new(3,3)
|
136
|
+
grid.map! { |value, row, column| (row * grid.columns) + column }
|
137
|
+
|
138
|
+
grid.store # => [0,1,2,3,4,5,6,7,8]
|
139
|
+
```
|
140
|
+
|
141
|
+
#### Row
|
142
|
+
|
143
|
+
You can update a specific row if needed, for example, if we want to update the middle row
|
144
|
+
|
145
|
+
```
|
146
|
+
GridStruct#map_row! { |value, column| # Return new value }
|
147
|
+
```
|
148
|
+
|
149
|
+
```
|
150
|
+
+---+---+---+
|
151
|
+
| 0 | 1 | 2 |
|
152
|
+
+---+---+---+
|
153
|
+
Update this row → | 3 | 4 | 5 |
|
154
|
+
+---+---+---+
|
155
|
+
| 6 | 7 | 8 |
|
156
|
+
+---+---+---+
|
157
|
+
```
|
158
|
+
|
159
|
+
```ruby
|
160
|
+
grid.map_row!(1) { |value| value * 10 }
|
161
|
+
|
162
|
+
grid.store # => [0,1,2,30,40,50,6,7,8]
|
163
|
+
```
|
164
|
+
|
165
|
+
|
166
|
+
#### Column
|
167
|
+
|
168
|
+
You can update a specific row if needed, for example, if we want to update the middle row
|
169
|
+
|
170
|
+
```
|
171
|
+
GridStruct#map_column! { |value, row| # Return new value }
|
172
|
+
```
|
173
|
+
|
174
|
+
```
|
175
|
+
Update this columns
|
176
|
+
↓
|
177
|
+
+---+---+---+
|
178
|
+
| 0 | 1 | 2 |
|
179
|
+
+---+---+---+
|
180
|
+
| 3 | 4 | 5 |
|
181
|
+
+---+---+---+
|
182
|
+
| 6 | 7 | 8 |
|
183
|
+
+---+---+---+
|
184
|
+
```
|
185
|
+
|
186
|
+
```ruby
|
187
|
+
grid.map_column!(2) { |value| value * 10 }
|
188
|
+
|
189
|
+
grid.store # => [0,1,20,3,4,50,6,7,80]
|
190
|
+
```
|
191
|
+
|
192
|
+
### Selectors
|
193
|
+
|
194
|
+
Selector gives you access to line of values within the grid, and allows you to
|
195
|
+
only act on that line. Each selector return a (or an array of) GridStruct::Selector.
|
196
|
+
|
197
|
+
#### Overview
|
198
|
+
|
199
|
+
A selector has the following instances:
|
200
|
+
|
201
|
+
- ``grid``: The grid it is selecting from
|
202
|
+
- ``indexes``: An array of indexes mapping to the selected values in the grid store
|
203
|
+
|
204
|
+
```ruby
|
205
|
+
grid = GridStruct.new(3,3)
|
206
|
+
|
207
|
+
grid.map! do |value, row, column|
|
208
|
+
(row * grid.columns + column) * 10
|
209
|
+
end
|
210
|
+
|
211
|
+
grid.row(0) # => #<GridStruct::Selector:0x007fb3d11decf0 @grid=#<GridStruct:0x007fb3d15541f0 @columns=3, @rows=3, @store=[0, 10, 20, 30, 40, 50, 60, 70, 80]>, @indexes=[0, 1, 2]>
|
212
|
+
```
|
213
|
+
|
214
|
+
You can retrieve and update values using ``[]``. It will map the action to the grid.
|
215
|
+
|
216
|
+
```ruby
|
217
|
+
first_row = grid.row(0)
|
218
|
+
|
219
|
+
first_row.to_a # => [0,10,20]
|
220
|
+
|
221
|
+
first_row[0] # => 0
|
222
|
+
first_row[1] # => 10
|
223
|
+
first_row[2] # => 20
|
224
|
+
|
225
|
+
first_row[0] = -100
|
226
|
+
|
227
|
+
grid.to_a # => [-100,10,20,30,40,50,60,70,80]
|
228
|
+
|
229
|
+
```
|
230
|
+
|
231
|
+
#### Row
|
232
|
+
|
233
|
+
To select a specific row, use the method ``row``
|
234
|
+
|
235
|
+
```
|
236
|
+
GridStruct#row(row_number)
|
237
|
+
```
|
238
|
+
|
239
|
+
```ruby
|
240
|
+
rows = []
|
241
|
+
|
242
|
+
# Fetch selector for every rows
|
243
|
+
grid.rows.times.each do |row_index|
|
244
|
+
rows[row_index] = grid.row(row_index)
|
245
|
+
end
|
246
|
+
```
|
247
|
+
|
248
|
+
#### Column
|
249
|
+
|
250
|
+
To select a specific column, use the method ``column``
|
251
|
+
|
252
|
+
```
|
253
|
+
GridStruct#column(column_number)
|
254
|
+
```
|
255
|
+
|
256
|
+
```ruby
|
257
|
+
columns = []
|
258
|
+
|
259
|
+
# Fetch selector for every columns
|
260
|
+
grid.columns.times.each do |column_index|
|
261
|
+
columns[column_index] = grid.column(column_index)
|
262
|
+
end
|
263
|
+
```
|
264
|
+
|
265
|
+
#### Diagonals
|
266
|
+
|
267
|
+
The diagonals retrieval works slightly differently from the two previous methods.
|
268
|
+
In order to retrieve diagonals, you must provide the coordinates of a cell in the grid. This will retrieve the diagonals that cross through that specific cell.
|
269
|
+
The returned array can be of size 0 (no diagonals found, for example, in a grid of size 1), 1 (when retrieving diagonals from the corners of the grid) or 2.
|
270
|
+
|
271
|
+
```
|
272
|
+
GridStruct#diagonals(1,1) # => [#<GridStruct::Selector ...>, #<GridStruct::Selector ...>]
|
273
|
+
```
|
274
|
+
|
275
|
+
```ruby
|
276
|
+
diagonals = grid.diagonals(1,1)
|
277
|
+
|
278
|
+
diagonals.first.to_a # => [0,40,80]
|
279
|
+
diagonals.last.to_a # => [30,40,60]
|
280
|
+
|
281
|
+
corner_diagonal = grid.diagonals(0,0) # fetch diagonals from top left corner
|
282
|
+
|
283
|
+
corner_diagonal.size # => 1
|
284
|
+
corner_diagonal.first.to_a # => [0,40,80]
|
285
|
+
```
|
286
|
+
|
287
|
+
#### Slice
|
288
|
+
|
289
|
+
Imagine a slice as a projection of a section of your grid.
|
290
|
+
Use the ``slice`` method to access a single slice.
|
291
|
+
|
292
|
+
```
|
293
|
+
GridStruct#slice(slice_index, rows: slice_rows, columns: slice_columns) # => #<GridStruct::Selector ...>
|
294
|
+
```
|
295
|
+
|
296
|
+
In the following example, we are manipulating a sudoku grid, and we want to access the middle 3x3 square
|
297
|
+
|
298
|
+
```ruby
|
299
|
+
sudoku_grid = GridStruct.new(9,9)
|
300
|
+
|
301
|
+
sudoku_grid.map! do |v, r, c|
|
302
|
+
(r * sudoku_grid.columns) + c + 1
|
303
|
+
end
|
304
|
+
|
305
|
+
sudoku_grid.slice(4, rows: 3, columns: 3) # => #<GridStruct:0x007fb3d16e4e70 @columns=3, @rows=3, @store=[31, 32, 33, 40, 41, 42, 49, 50, 51]>
|
306
|
+
```
|
307
|
+
|
308
|
+
Use the ``each_slice`` method to go through each slices
|
309
|
+
|
310
|
+
```
|
311
|
+
GridStruct#each_slice(slice_rows,slice_columns) { |slice, slice_index| # Do something }
|
312
|
+
```
|
313
|
+
|
314
|
+
```ruby
|
315
|
+
sudoku_grid.each_slice(3,3) do |slice, index|
|
316
|
+
# Do something
|
317
|
+
end
|
318
|
+
```
|
319
|
+
|
320
|
+
## Contributing
|
321
|
+
|
322
|
+
1. Fork it
|
323
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
324
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
325
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
326
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/grid_struct.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'grid_struct/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "grid_struct"
|
8
|
+
spec.version = GridStruct::VERSION
|
9
|
+
spec.authors = ["Samuel Molinari"]
|
10
|
+
spec.email = ["samuel@molinari.me"]
|
11
|
+
spec.description = %q{Grid data structure}
|
12
|
+
spec.summary = %q{Handle a grid data structure}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
spec.add_development_dependency "guard"
|
25
|
+
spec.add_development_dependency "guard-rspec"
|
26
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class ::GridStruct::Selector
|
2
|
+
|
3
|
+
attr_reader :grid, :indexes, :rows, :columns
|
4
|
+
|
5
|
+
def initialize(grid,*indexes)
|
6
|
+
@grid = grid
|
7
|
+
@indexes = indexes.freeze
|
8
|
+
end
|
9
|
+
|
10
|
+
def dimensions(rows,columns)
|
11
|
+
@rows = rows
|
12
|
+
@columns = columns
|
13
|
+
return self
|
14
|
+
end
|
15
|
+
|
16
|
+
def [](i)
|
17
|
+
mapped_index = @indexes[i]
|
18
|
+
mapped_index.nil? ? nil : @grid.store[mapped_index]
|
19
|
+
end
|
20
|
+
|
21
|
+
def []=(i,value)
|
22
|
+
mapped_index = @indexes[i]
|
23
|
+
@grid.store[mapped_index] = value unless mapped_index.nil?
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_a
|
27
|
+
@indexes.size.times.map do |i|
|
28
|
+
self[i]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_grid(rows = nil,columns = nil)
|
33
|
+
rows ||= @rows
|
34
|
+
columns ||= @columns
|
35
|
+
GridStruct.new(rows,columns,to_a)
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
data/lib/grid_struct.rb
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
require 'grid_struct/version'
|
2
|
+
require 'grid_struct/selector'
|
3
|
+
|
4
|
+
class GridStruct
|
5
|
+
|
6
|
+
attr_reader :store,
|
7
|
+
:rows,
|
8
|
+
:columns
|
9
|
+
|
10
|
+
def initialize(rows, columns, store = [])
|
11
|
+
@rows = rows
|
12
|
+
@columns = columns
|
13
|
+
@store = store || []
|
14
|
+
end
|
15
|
+
|
16
|
+
def set(row,column)
|
17
|
+
@store[get_index(row,column)] = yield
|
18
|
+
end
|
19
|
+
|
20
|
+
def map!
|
21
|
+
size.times.map do |index|
|
22
|
+
value = @store[index]
|
23
|
+
row_column = get_row_column_at(index)
|
24
|
+
@store[index] = yield(value, row_column[:row], row_column[:column])
|
25
|
+
end
|
26
|
+
return self
|
27
|
+
end
|
28
|
+
|
29
|
+
def map_row!(n)
|
30
|
+
@columns.times.each do |column|
|
31
|
+
index = get_index(n,column)
|
32
|
+
value = @store[index]
|
33
|
+
@store[index] = yield(value,column)
|
34
|
+
end
|
35
|
+
return self
|
36
|
+
end
|
37
|
+
|
38
|
+
def map_column!(n)
|
39
|
+
@rows.times.each do |row|
|
40
|
+
index = get_index(row,n)
|
41
|
+
value = @store[index]
|
42
|
+
@store[index] = yield(value,row)
|
43
|
+
end
|
44
|
+
return self
|
45
|
+
end
|
46
|
+
|
47
|
+
def each
|
48
|
+
@store.fill(nil,@store.size...size).each.with_index do |value, index|
|
49
|
+
row_column = get_row_column_at(index)
|
50
|
+
yield(value,row_column[:row],row_column[:column])
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def each_slice(rows,columns)
|
55
|
+
sub_rows = (@rows / rows.to_f).ceil
|
56
|
+
sub_columns = (@columns / columns.to_f).ceil
|
57
|
+
|
58
|
+
sub_rows.times.each do |sub_row|
|
59
|
+
sub_columns.ceil.times.each do |sub_column|
|
60
|
+
|
61
|
+
index = sub_column + (sub_row * sub_columns)
|
62
|
+
yield(slice(index, rows: rows, columns: columns), index)
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def get(row,column)
|
69
|
+
@store[get_index(row,column)]
|
70
|
+
end
|
71
|
+
|
72
|
+
##
|
73
|
+
# TODO Improve
|
74
|
+
def slice(index,dimensions)
|
75
|
+
rows = dimensions[:rows]
|
76
|
+
columns = dimensions[:columns]
|
77
|
+
sub_columns = (@columns / columns.to_f).ceil
|
78
|
+
|
79
|
+
sub_row = index / sub_columns
|
80
|
+
sub_column = index - (sub_row * sub_columns)
|
81
|
+
|
82
|
+
indexes = []
|
83
|
+
rows.times.each do |r|
|
84
|
+
start_index = (r * @columns) +
|
85
|
+
(sub_row * rows * @columns) +
|
86
|
+
(sub_column * columns)
|
87
|
+
end_index = start_index + columns
|
88
|
+
|
89
|
+
start_row = get_row_column_at(start_index)[:row]
|
90
|
+
end_row = get_row_column_at(end_index)[:row]
|
91
|
+
|
92
|
+
if start_row != end_row
|
93
|
+
extras = [0,(end_index - @columns)].max % @columns
|
94
|
+
end_index -= extras
|
95
|
+
end
|
96
|
+
|
97
|
+
final_row_indexes = (start_index...end_index).to_a
|
98
|
+
final_row_indexes.fill(nil,final_row_indexes.size...columns)
|
99
|
+
indexes += final_row_indexes
|
100
|
+
end
|
101
|
+
|
102
|
+
return GridStruct::Selector.new(self, *indexes).dimensions(rows,columns)
|
103
|
+
end
|
104
|
+
|
105
|
+
def row(n)
|
106
|
+
start_index = (n * @columns)
|
107
|
+
end_index = start_index + @columns
|
108
|
+
GridStruct::Selector.new(self,*(start_index...end_index))
|
109
|
+
end
|
110
|
+
|
111
|
+
def column(n)
|
112
|
+
GridStruct::Selector.new(self,*@rows.times.map do |row|
|
113
|
+
get_index(row,n)
|
114
|
+
end)
|
115
|
+
end
|
116
|
+
|
117
|
+
def diagonals(row,column)
|
118
|
+
selectors = []
|
119
|
+
|
120
|
+
first = diagonal_builder({row: row, column: column})
|
121
|
+
second = diagonal_builder({row: row, column: column}, 1, -1)
|
122
|
+
|
123
|
+
selectors.push(GridStruct::Selector.new(self, *first)) if first.size > 1
|
124
|
+
selectors.push(GridStruct::Selector.new(self, *second)) if second.size > 1
|
125
|
+
|
126
|
+
return selectors
|
127
|
+
end
|
128
|
+
|
129
|
+
def size
|
130
|
+
@rows * @columns
|
131
|
+
end
|
132
|
+
|
133
|
+
def to_a
|
134
|
+
store_size = @store.size
|
135
|
+
return @store.dup.fill(nil,store_size...size)
|
136
|
+
end
|
137
|
+
|
138
|
+
def ==(other)
|
139
|
+
@store == other.instance_variable_get(:@store)
|
140
|
+
end
|
141
|
+
|
142
|
+
protected
|
143
|
+
|
144
|
+
def get_index(row,column)
|
145
|
+
(row * @columns) + column
|
146
|
+
end
|
147
|
+
|
148
|
+
def get_row_column_at(index)
|
149
|
+
row = index / @columns
|
150
|
+
column = index - (row * @columns)
|
151
|
+
return { row: row, column: column }
|
152
|
+
end
|
153
|
+
|
154
|
+
def diagonal_builder(coordinates, row_direction = 1, column_direction = 1, diagonal_indexes = [], action = :push)
|
155
|
+
row = coordinates[:row]
|
156
|
+
column = coordinates[:column]
|
157
|
+
index = get_index(row,column)
|
158
|
+
|
159
|
+
if !diagonal_indexes.include?(index) &&
|
160
|
+
row >= 0 &&
|
161
|
+
column >= 0 &&
|
162
|
+
row < @rows &&
|
163
|
+
column < @columns
|
164
|
+
|
165
|
+
diagonal_indexes.method(action).call(get_index(row,column))
|
166
|
+
|
167
|
+
diagonal_builder({ row: row - (row_direction * 1),
|
168
|
+
column: column - (column_direction * 1) },
|
169
|
+
row_direction,
|
170
|
+
column_direction,
|
171
|
+
diagonal_indexes,
|
172
|
+
:unshift)
|
173
|
+
|
174
|
+
diagonal_builder({ row: row + (row_direction * 1),
|
175
|
+
column: column + (column_direction * 1) },
|
176
|
+
row_direction,
|
177
|
+
column_direction,
|
178
|
+
diagonal_indexes,
|
179
|
+
:push)
|
180
|
+
|
181
|
+
end
|
182
|
+
|
183
|
+
return diagonal_indexes
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ::GridStruct::Selector do
|
4
|
+
|
5
|
+
let(:grid) { GridStruct.new(9,9) }
|
6
|
+
let(:indexes) { [0,3,34,57] }
|
7
|
+
subject(:selector) { described_class.new(grid,*indexes) }
|
8
|
+
|
9
|
+
before(:each) do
|
10
|
+
grid.map! do |value,row,column|
|
11
|
+
((row * grid.columns) + column) * 2
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it { is_expected.to have_attributes(grid: grid,
|
16
|
+
indexes: indexes) }
|
17
|
+
|
18
|
+
describe '#[]' do
|
19
|
+
it 'retrieve the x element in the current selection' do
|
20
|
+
expect(selector[0]).to eq 0
|
21
|
+
expect(selector[1]).to eq 6
|
22
|
+
expect(selector[2]).to eq 68
|
23
|
+
expect(selector[3]).to eq 114
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'when mapped index is nil' do
|
27
|
+
let(:broken_selector) { described_class.new(grid, [0,nil,nil,nil]) }
|
28
|
+
|
29
|
+
it 'returns nil' do
|
30
|
+
expect(broken_selector[1]).to be_nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#[]=' do
|
36
|
+
it 'sets the value in the grid through the selector' do
|
37
|
+
selector[0] = -10
|
38
|
+
selector[1] = -3
|
39
|
+
selector[2] = 'hello world'
|
40
|
+
expect(grid.store[0]).to eq -10
|
41
|
+
expect(grid.store[3]).to eq -3
|
42
|
+
expect(grid.store[34]).to eq 'hello world'
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when mapped index is nil' do
|
46
|
+
let(:broken_selector) { described_class.new(grid, [0,nil,nil,nil]) }
|
47
|
+
|
48
|
+
it 'ignores action' do
|
49
|
+
store = grid.store
|
50
|
+
broken_selector[1] = 100
|
51
|
+
expect(grid.store).to eq store
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#dimensions' do
|
57
|
+
it 'sets the virtual dimensions of the current selection' do
|
58
|
+
selector.dimensions(2,3)
|
59
|
+
expect(selector.rows).to eq 2
|
60
|
+
expect(selector.columns).to eq 3
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#to_a' do
|
65
|
+
it 'fetches and returns selector values into an array' do
|
66
|
+
expect(selector.to_a).to eq [0,6,68,114]
|
67
|
+
end
|
68
|
+
it 'does not modify the grid when manipulating retuning array' do
|
69
|
+
array = selector.to_a
|
70
|
+
array[0] = -100
|
71
|
+
expect(grid.store[0]).not_to eq -100
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe 'to_grid' do
|
76
|
+
it 'converts current selection into a new grid, with the given dimensions' do
|
77
|
+
expect(selector.to_grid(2,2)).to eq GridStruct.new(2,2,[0,6,68,114])
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
@@ -0,0 +1,296 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ::GridStruct do
|
4
|
+
|
5
|
+
let(:sudoku_grid) { GridStruct.new(9,9) }
|
6
|
+
before(:each) do
|
7
|
+
# Fill grid as such
|
8
|
+
#
|
9
|
+
# |----|----|----|----|----|----|----|----|----|
|
10
|
+
# | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|
11
|
+
# |----|----|----|----|----|----|----|----|----|
|
12
|
+
# | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
|
13
|
+
# |----|----|----|----|----|----|----|----|----|
|
14
|
+
# | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
|
15
|
+
# |----|----|----|----|----|----|----|----|----|
|
16
|
+
# | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
|
17
|
+
# |----|----|----|----|----|----|----|----|----|
|
18
|
+
# | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
|
19
|
+
# |----|----|----|----|----|----|----|----|----|
|
20
|
+
# | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 |
|
21
|
+
# |----|----|----|----|----|----|----|----|----|
|
22
|
+
# | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
|
23
|
+
# |----|----|----|----|----|----|----|----|----|
|
24
|
+
# | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 |
|
25
|
+
# |----|----|----|----|----|----|----|----|----|
|
26
|
+
# | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 |
|
27
|
+
# |----|----|----|----|----|----|----|----|----|
|
28
|
+
|
29
|
+
sudoku_grid.map! do |value, row, column|
|
30
|
+
row * sudoku_grid.columns + column
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
let(:rows) { 2 }
|
35
|
+
let(:columns) { 3 }
|
36
|
+
subject(:grid) { GridStruct.new(rows, columns) }
|
37
|
+
|
38
|
+
it { is_expected.to have_attributes(rows: rows,
|
39
|
+
columns: columns) }
|
40
|
+
|
41
|
+
describe '#size' do
|
42
|
+
it 'is the multiplication of with and height' do
|
43
|
+
expect(grid.size).to be rows * columns
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#set' do
|
48
|
+
it 'sets the value at the given row and column' do
|
49
|
+
grid.set(0,0) { 1 }
|
50
|
+
store = grid.instance_variable_get(:@store)
|
51
|
+
expect(store).to eq [1]
|
52
|
+
|
53
|
+
grid.set(1,0) { 2 }
|
54
|
+
store = grid.instance_variable_get(:@store)
|
55
|
+
expect(store).to eq [1,nil,nil,2]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '#each' do
|
60
|
+
before(:each) do
|
61
|
+
grid.instance_variable_set(:@store, [0,1,2,3,4,5])
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'iterates through each elements of the grid (left to right, top to bottom)' do
|
65
|
+
values = []
|
66
|
+
grid.each do |element,row,column|
|
67
|
+
values[(row * grid.columns) + column] = element
|
68
|
+
end
|
69
|
+
expect(values.size).to be grid.size
|
70
|
+
expect(values).to eq grid.to_a
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '#map!' do
|
75
|
+
it 'replaces all the elements in the grid' do
|
76
|
+
grid.map! do |value, row, column|
|
77
|
+
(row + 1) * (column + 1)
|
78
|
+
end
|
79
|
+
store = grid.instance_variable_get(:@store)
|
80
|
+
expect(store).to eq [1,2,3,2,4,6]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '#map_row!' do
|
85
|
+
it 'replaces the elements in the targeted row' do
|
86
|
+
grid.map_row!(0) { |value, column| column }
|
87
|
+
store = grid.instance_variable_get(:@store)
|
88
|
+
expect(store).to eq [0,1,2]
|
89
|
+
|
90
|
+
grid.map_row!(1) { |value, column| column**2 }
|
91
|
+
store = grid.instance_variable_get(:@store)
|
92
|
+
expect(store).to eq [0,1,2,0,1,4]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '#map_column!' do
|
97
|
+
it 'replaces the elements in the targeted column' do
|
98
|
+
grid.map_column!(0) { |value, row| row }
|
99
|
+
store = grid.instance_variable_get(:@store)
|
100
|
+
expect(store).to eq [0,nil,nil,1]
|
101
|
+
|
102
|
+
grid.map_column!(1) { |value, row| row + 1 }
|
103
|
+
store = grid.instance_variable_get(:@store)
|
104
|
+
expect(store).to eq [0,1,nil,1,2]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe '#each_slice' do
|
109
|
+
it 'iterates through sub-grids of the given rows and columns' do
|
110
|
+
sub_grids = []
|
111
|
+
sudoku_grid.each_slice(3,3) do |sub_grid,index|
|
112
|
+
sub_grids[index] = sub_grid
|
113
|
+
end
|
114
|
+
expect(sub_grids[0].to_a).to eq [0,1,2,9,10,11,18,19,20]
|
115
|
+
expect(sub_grids[1].to_a).to eq [3,4,5,12,13,14,21,22,23]
|
116
|
+
expect(sub_grids[2].to_a).to eq [6,7,8,15,16,17,24,25,26]
|
117
|
+
expect(sub_grids[3].to_a).to eq [27,28,29,36,37,38,45,46,47]
|
118
|
+
expect(sub_grids[4].to_a).to eq [30,31,32,39,40,41,48,49,50]
|
119
|
+
expect(sub_grids[5].to_a).to eq [33,34,35,42,43,44,51,52,53]
|
120
|
+
expect(sub_grids[6].to_a).to eq [54,55,56,63,64,65,72,73,74]
|
121
|
+
expect(sub_grids[7].to_a).to eq [57,58,59,66,67,68,75,76,77]
|
122
|
+
expect(sub_grids[8].to_a).to eq [60,61,62,69,70,71,78,79,80]
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'when slice is equal to the grid' do
|
126
|
+
it 'iterates a single time with a copy of the current grid' do
|
127
|
+
selector = nil
|
128
|
+
sudoku_grid.each_slice(9,9) do |sub_grid|
|
129
|
+
selector = sub_grid
|
130
|
+
end
|
131
|
+
expect(selector.to_grid).to eq sudoku_grid
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context 'when slice is bigger than the grid' do
|
136
|
+
it 'iterates a single time with content of current grid with extra edges' do
|
137
|
+
selector = nil
|
138
|
+
sudoku_grid.each_slice(10,10) do |sub_grid|
|
139
|
+
selector = sub_grid
|
140
|
+
end
|
141
|
+
sudoku_grid.rows.times.each do |row_index|
|
142
|
+
expect(selector.to_grid.row(row_index).to_a).to eq (sudoku_grid.row(row_index).to_a + [nil])
|
143
|
+
end
|
144
|
+
sudoku_grid.columns.times.each do |column_index|
|
145
|
+
expect(selector.to_grid.column(column_index).to_a).to eq (sudoku_grid.column(column_index).to_a + [nil])
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context 'when last slice bleeds out of the grid' do
|
151
|
+
it 'nullify the extras' do
|
152
|
+
sub_grids = []
|
153
|
+
sudoku_grid.each_slice(2,4) do |sub_grid,index|
|
154
|
+
sub_grids[index] = sub_grid
|
155
|
+
end
|
156
|
+
expect(sub_grids[2].to_a).to eq [8,nil,nil,nil,17,nil,nil,nil]
|
157
|
+
expect(sub_grids[5].to_a).to eq [26,nil,nil,nil,35,nil,nil,nil]
|
158
|
+
expect(sub_grids[8].to_a).to eq [44,nil,nil,nil,53,nil,nil,nil]
|
159
|
+
expect(sub_grids[11].to_a).to eq [62,nil,nil,nil,71,nil,nil,nil]
|
160
|
+
expect(sub_grids[12].to_a).to eq [72,73,74,75,nil,nil,nil,nil]
|
161
|
+
expect(sub_grids[13].to_a).to eq [76,77,78,79,nil,nil,nil,nil]
|
162
|
+
expect(sub_grids[14].to_a).to eq [80,nil,nil,nil,nil,nil,nil,nil]
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
describe '#get' do
|
168
|
+
context 'a non-set cell' do
|
169
|
+
it 'returns nil' do
|
170
|
+
expect(grid.get(0,0)).to be_nil
|
171
|
+
end
|
172
|
+
end
|
173
|
+
context 'an already set cell' do
|
174
|
+
before(:each) do
|
175
|
+
grid.instance_variable_set(:@store, [nil,8,nil,9,2,nil])
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'returns the stored value at the given row and column' do
|
179
|
+
expect(grid.get(0,0)).to be_nil
|
180
|
+
expect(grid.get(0,1)).to be 8
|
181
|
+
expect(grid.get(0,2)).to be_nil
|
182
|
+
expect(grid.get(1,0)).to be 9
|
183
|
+
expect(grid.get(1,1)).to be 2
|
184
|
+
expect(grid.get(1,2)).to be_nil
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
describe '#row' do
|
190
|
+
before(:each) do
|
191
|
+
grid.instance_variable_set(:@store, [nil,8,nil,9,2,nil])
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'returns a selector' do
|
195
|
+
expect(grid.row(0)).to be_kind_of(GridStruct::Selector)
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'retrieves a selector of the requested row' do
|
199
|
+
expect(grid.row(0).to_a).to eq [nil,8,nil]
|
200
|
+
expect(grid.row(1).to_a).to eq [9,2,nil]
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
describe '#column' do
|
205
|
+
before(:each) do
|
206
|
+
grid.instance_variable_set(:@store, [nil,8,nil,9,2,nil])
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'returns a selector' do
|
210
|
+
expect(grid.column(0)).to be_kind_of(GridStruct::Selector)
|
211
|
+
end
|
212
|
+
|
213
|
+
it 'retrieves a selector of the requested column' do
|
214
|
+
expect(grid.column(0).to_a).to eq [nil,9]
|
215
|
+
expect(grid.column(1).to_a).to eq [8,2]
|
216
|
+
expect(grid.column(2).to_a).to eq [nil,nil]
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
describe '#diagonals' do
|
221
|
+
it 'returns an array' do
|
222
|
+
expect(grid.diagonals(0,0)).to be_kind_of Array
|
223
|
+
end
|
224
|
+
|
225
|
+
context 'when fetching diagonals not from a corner' do
|
226
|
+
it 'returns 2 selectors' do
|
227
|
+
diagonals = sudoku_grid.diagonals(4,4)
|
228
|
+
expect(diagonals.size).to be 2
|
229
|
+
expect(diagonals.first).to be_kind_of(GridStruct::Selector)
|
230
|
+
expect(diagonals.last).to be_kind_of(GridStruct::Selector)
|
231
|
+
end
|
232
|
+
|
233
|
+
it 'returns the diagonals crossing the given coordinates' do
|
234
|
+
diagonals = sudoku_grid.diagonals(4,4)
|
235
|
+
expect(diagonals.first.to_a).to eq [0,10,20,30,40,50,60,70,80]
|
236
|
+
expect(diagonals.last.to_a).to eq [8,16,24,32,40,48,56,64,72]
|
237
|
+
end
|
238
|
+
|
239
|
+
context 'the returned selectors' do
|
240
|
+
it 'approprietly modify its matching element' do
|
241
|
+
diagonals = sudoku_grid.diagonals(4,4)
|
242
|
+
diagonals.first[4] = -100
|
243
|
+
expect(sudoku_grid.get(4,4))
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
context 'when fetching diagonals from a corner' do
|
249
|
+
it 'only returns 1 diagonal selector' do
|
250
|
+
expect(sudoku_grid.diagonals(0,0).size).to be 1
|
251
|
+
expect(sudoku_grid.diagonals(0,sudoku_grid.columns - 1).size).to be 1
|
252
|
+
expect(sudoku_grid.diagonals(sudoku_grid.rows - 1,0).size).to be 1
|
253
|
+
expect(sudoku_grid.diagonals(sudoku_grid.rows - 1, sudoku_grid.columns - 1).size).to be 1
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
describe '#slice' do
|
259
|
+
it 'returns a selector' do
|
260
|
+
expect(sudoku_grid.slice(0, rows: 3, columns: 3)).to be_kind_of(GridStruct::Selector)
|
261
|
+
end
|
262
|
+
|
263
|
+
context 'the returned selector' do
|
264
|
+
it 'modifies its matching element' do
|
265
|
+
slice = sudoku_grid.slice(0, rows: 3, columns: 3)
|
266
|
+
slice[4] = -100
|
267
|
+
expect(sudoku_grid.get(1,1)).to eq -100
|
268
|
+
end
|
269
|
+
|
270
|
+
context 'when slice goes out of bound' do
|
271
|
+
it 'adds extras when converting to grid' do
|
272
|
+
slice = sudoku_grid.slice(2, rows: 2, columns: 4)
|
273
|
+
expect(slice.to_grid.to_a).to eq [8,nil,nil,nil,17,nil,nil,nil]
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
describe '#to_a' do
|
280
|
+
it 'returns an array matching size of the grid' do
|
281
|
+
expect(grid.to_a.size).to be grid.size
|
282
|
+
end
|
283
|
+
|
284
|
+
it 'returns content of grid store' do
|
285
|
+
grid.instance_variable_set(:@store, [0,1,2,3,4,5])
|
286
|
+
expect(grid.to_a).to eq [0,1,2,3,4,5]
|
287
|
+
end
|
288
|
+
|
289
|
+
it 'returns a copy' do
|
290
|
+
grid.instance_variable_set(:@store, [0,1,2,3,4,5])
|
291
|
+
array = grid.to_a
|
292
|
+
array[0] = 100
|
293
|
+
expect(grid.get(0,0)).to be 0
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: grid_struct
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Samuel Molinari
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-11-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: guard
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: guard-rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: Grid data structure
|
84
|
+
email:
|
85
|
+
- samuel@molinari.me
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- .gitignore
|
91
|
+
- .rspec
|
92
|
+
- Gemfile
|
93
|
+
- Guardfile
|
94
|
+
- LICENSE.txt
|
95
|
+
- README.md
|
96
|
+
- Rakefile
|
97
|
+
- grid_struct.gemspec
|
98
|
+
- lib/grid_struct.rb
|
99
|
+
- lib/grid_struct/selector.rb
|
100
|
+
- lib/grid_struct/version.rb
|
101
|
+
- spec/lib/grid_struct/selector_spec.rb
|
102
|
+
- spec/lib/grid_struct_spec.rb
|
103
|
+
- spec/spec_helper.rb
|
104
|
+
homepage: ''
|
105
|
+
licenses:
|
106
|
+
- MIT
|
107
|
+
metadata: {}
|
108
|
+
post_install_message:
|
109
|
+
rdoc_options: []
|
110
|
+
require_paths:
|
111
|
+
- lib
|
112
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - '>='
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - '>='
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
requirements: []
|
123
|
+
rubyforge_project:
|
124
|
+
rubygems_version: 2.0.6
|
125
|
+
signing_key:
|
126
|
+
specification_version: 4
|
127
|
+
summary: Handle a grid data structure
|
128
|
+
test_files:
|
129
|
+
- spec/lib/grid_struct/selector_spec.rb
|
130
|
+
- spec/lib/grid_struct_spec.rb
|
131
|
+
- spec/spec_helper.rb
|