aoc_rb_helpers 0.0.4 → 0.0.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ab9f12989f97afbeb704d8439ba020351f1288f8519683aaca95cae2cadb5d47
4
- data.tar.gz: ddfc599e4d027bb4b55e2b6d83b02c3ce19146d01a37345ac59487ea9272ec6c
3
+ metadata.gz: 1990cde2622df33946ce6131918c215ac548d3b013ed36b57fd980fd0ba7c0ab
4
+ data.tar.gz: 7070a8add7b5f3bf0b4fa033959ce30624edeac87329a95964e2bade9dbb5741
5
5
  SHA512:
6
- metadata.gz: 788dc4890a2955752e00e9071363f973396c3f4b1a89d3340d59bd382bdc38158d13677568f400c8b2ad84124b1bb1620ba8a187426c018ad2d7edc5903f7ba6
7
- data.tar.gz: e3e73b45faf9044fd73c74289d5bdaa1e9d09c28cd42d913f6c47ffe577b69379827f88bf867b044a90db1cda39fb47c9f15f08d00b4ad7e9d547b67f37bfc7e
6
+ metadata.gz: 402844433642a9dcfd4bcded006ec9eca2d3cc8b18a0016b7d3cc45631b24e54e37315af3cff1d895c511233a167b9cc82ed21f7f942f721cafe016f8ea552d6
7
+ data.tar.gz: 34f664b1de9a6fd751241afc34445c46cc16ab6cce24f246476799d7915ce4f519f4ac67d22a42b72780c673d5c21fe693c19c42786a23f6b529c19beffa53f8
data/CHANGELOG.md CHANGED
@@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
  ## [Unreleased]
8
8
  - No unreleased changes!
9
9
 
10
+ ## [0.0.5]
11
+ ### Added
12
+ - AocInput#process_each_line - Processes each line of the input data using the provided block
13
+ - Grid#includes_coords? - Returns `true` if the provided coordinates exist within the bounds of the grid
14
+ - Grid#beyond_grid? - Returns `true` if the provided coordinates exceed the bounds of the grid
15
+ - Grid#locate(value) - Returns the first coordinates within the grid containing the given value
16
+ - Grid#locate_all(value) - Returns an array of coordinates for any location within the grid containing the given value
17
+ - Grid#each_cell - Iterates over each cell in the grid
18
+
19
+ ### Changed
20
+ - Grid#cell now returns `nil` if the provided coordinates to not exist within the grid
21
+ - Grid#set_cell nwo returns `nil` if the provided coordinates to not exist within the grid
22
+
23
+ ### Fixed
24
+ - Grid#dup previously returned a new `Grid` instance with the same instance of the `@grid` array within it. Now `@grid` is a unique copy.
25
+
10
26
  ## [0.0.4]
11
27
  ### Added
12
28
  - Grid class for working with two-dimensional arrays of data
@@ -29,6 +45,9 @@ Initial release.
29
45
  ### Added
30
46
  - Created `AocInput` class with initial helper methods
31
47
 
32
- [Unreleased]: https://github.com/pacso/aoc_rb_helpers/compare/v0.0.2...HEAD
48
+ [Unreleased]: https://github.com/pacso/aoc_rb_helpers/compare/v0.0.5...HEAD
49
+ [0.0.5]: https://github.com/pacso/aoc_rb_helpers/compare/v0.0.4...v0.0.5
50
+ [0.0.4]: https://github.com/pacso/aoc_rb_helpers/compare/v0.0.3...v0.0.4
51
+ [0.0.3]: https://github.com/pacso/aoc_rb_helpers/compare/v0.0.2...v0.0.3
33
52
  [0.0.2]: https://github.com/pacso/aoc_rb_helpers/compare/v0.0.1...v0.0.2
34
53
  [0.0.1]: https://github.com/pacso/aoc_rb_helpers
@@ -36,6 +36,26 @@ class AocInput
36
36
  self
37
37
  end
38
38
 
39
+ # Processes each line of the data using the provided block.
40
+ #
41
+ # This method applies the given block to each line in the +@data+ array,
42
+ # replacing the original +@data+ with the results of the block. The method
43
+ # returns +self+ to allow method chaining.
44
+ #
45
+ # Returns an enumerator if no block is given.
46
+ #
47
+ # @yieldparam line [Object, Array<Object>] a single line of the data being processed
48
+ # @yieldreturn [Object, Array<Object>] the result of processing the line
49
+ # @return [self] the instance itself, for method chaining
50
+ # @return [Enumerator] if no block is given
51
+ def process_each_line
52
+ return to_enum(__callee__) unless block_given?
53
+ @data = @data.map do |line|
54
+ yield line
55
+ end
56
+ self
57
+ end
58
+
39
59
  # Splits each string in the data array into an array of numbers.
40
60
  #
41
61
  # This method processes +@data+ by splitting each string in the array using the specified delimiter,
@@ -16,23 +16,55 @@ class Grid
16
16
  @grid = grid
17
17
  end
18
18
 
19
+ # Returns +true+ if the provided coordinates exceed the bounds of the grid; +false+ otherwise.
20
+ #
21
+ # @param row [Integer] the row index to test
22
+ # @param column [Integer] the column index to test
23
+ # @return [Boolean]
24
+ # @see #includes_coords?
25
+ def beyond_grid?(row, column)
26
+ !includes_coords?(row, column)
27
+ end
28
+
29
+ # Returns +true+ if the provided coordinates exist within the bounds of the grid; +false+ otherwise.
30
+ #
31
+ # @param row [Integer] the row index to test
32
+ # @param column [Integer] the column index to test
33
+ # @return [Boolean]
34
+ # @see #beyond_grid?
35
+ def includes_coords?(row, column)
36
+ row >= 0 && column >= 0 && row < @grid.length && column < @grid.first.length
37
+ end
38
+ alias_method(:within_grid?, :includes_coords?)
39
+
19
40
  # Returns the value stored at coordinates +(row, column)+ within the grid.
20
41
  #
42
+ # Returns +nil+ if the provided coordinates do not exist within the grid.
43
+ #
21
44
  # Row and column numbers are zero-indexed.
22
45
  #
23
46
  # @param row [Integer] the row index of the desired cell
24
47
  # @param column [Integer] the column index of the desired cell
48
+ # @return [Object] the value at the given coordinates within the grid
49
+ # @return [nil] if the given coordinates do not exist within the grid
50
+ # @see #set_cell
25
51
  def cell(row, column)
52
+ return nil unless includes_coords?(row, column)
26
53
  @grid[row][column]
27
54
  end
28
55
 
29
56
  # Updates the cell at coordinates +(row, column)+ with the object provided in +value+; returns the given object.
30
57
  #
58
+ # Returns +nil+ if the provided coordinates do not exist within the grid.
59
+ #
31
60
  # @param row [Integer] the row index of the cell you wish to update
32
61
  # @param column [Integer] the column index of the cell you wish to update
33
62
  # @param value [Object] the object to assign to the selected grid cell
34
63
  # @return [Object] the given +value+
64
+ # @return [nil] if the provided coordinates do not exist within the grid
65
+ # @see #cell
35
66
  def set_cell(row, column, value)
67
+ return nil unless includes_coords?(row, column)
36
68
  @grid[row][column] = value
37
69
  end
38
70
 
@@ -80,7 +112,7 @@ class Grid
80
112
  # Returns a new {Grid} as a copy of self.
81
113
  # @return [Grid] a copy of +self+
82
114
  def dup
83
- Grid.new(@grid)
115
+ self.class.new(@grid.map { |row| row.map { |cell| cell } })
84
116
  end
85
117
 
86
118
  # Updates +self+ with a rotated grid and returns +self+.
@@ -126,4 +158,109 @@ class Grid
126
158
  raise ArgumentError unless columns.is_a?(Integer) && columns > 0 && columns <= @grid.first.length
127
159
  each_subgrid(rows, columns).to_a
128
160
  end
161
+
162
+ # Returns the first coordinates within the grid containing the given value. Returns +nil+ if not found.
163
+ #
164
+ # If given an array of values, the first coordinate matching any of the given values will be returned.
165
+ #
166
+ # Searches the grid from top left (+[0, 0]+) to bottom right, by scanning each row.
167
+ #
168
+ # @param value [Object, Array<Object>] the value, or array of values, to search for.
169
+ # @return [Array<Integer>] if the value was located, its coordinates are returned in a 2-item array where:
170
+ # - The first item is the row index.
171
+ # - The second item is the column index.
172
+ # @return [nil] if the value was not located
173
+ def locate(value)
174
+ result = nil
175
+ if value.is_a? Array
176
+ value.each do |e|
177
+ result = locate(e)
178
+ break unless result.nil?
179
+ end
180
+ else
181
+ result = locate_value value
182
+ end
183
+ result
184
+ end
185
+
186
+ # Returns an array of coordinates for any location within the grid containing the given value.
187
+ #
188
+ # If given an array of values, the coordinates of any cell matching any of the given values will be returned.
189
+ #
190
+ # @param value [Object, Array<Object>] the value, or array of values, to search for.
191
+ # @return [Array<Array<Integer>>] an array of coordinates. Each coordinate is a 2-item array where:
192
+ # - The first item is the row index.
193
+ # - The second item is the column index.
194
+ def locate_all(value)
195
+ locations = []
196
+
197
+ if value.is_a? Array
198
+ @grid.each_with_index.select { |row, _r_index| value.any? { |el| row.include?(el) } }.each do |row, r_index|
199
+ row.each_with_index do |cell, c_index|
200
+ locations << [r_index, c_index] if value.include?(cell)
201
+ end
202
+ end
203
+ else
204
+ @grid.each_with_index.select { |row, _r_index| row.include?(value) }.each do |row, r_index|
205
+ row.each_with_index do |cell, c_index|
206
+ locations << [r_index, c_index] if cell == value
207
+ end
208
+ end
209
+ end
210
+
211
+ locations
212
+ end
213
+
214
+ # Iterates over each cell in the grid.
215
+ #
216
+ # When a block is given, passes the coordinates and value of each cell to the block; returns +self+:
217
+ # g = Grid.new([
218
+ # ["a", "b"],
219
+ # ["c", "d"]
220
+ # ])
221
+ # g.each_cell { |coords, value| puts "#{coords.inspect} => #{value}" }
222
+ #
223
+ # Output:
224
+ # [0, 0] => a
225
+ # [0, 1] => b
226
+ # [1, 0] => c
227
+ # [1, 1] => d
228
+ #
229
+ # When no block is given, returns a new Enumerator:
230
+ # g = Grid.new([
231
+ # [:a, "b"],
232
+ # [3, true]
233
+ # ])
234
+ # e = g.each_cell
235
+ # e # => #<Enumerator: #<Grid: @grid=[[\"a\", \"b\"], [\"c\", \"d\"]]>:each_cell>
236
+ # g1 = e.each { |coords, value| puts "#{coords.inspect} => #{value.class}: #{value}" }
237
+ #
238
+ # Output:
239
+ # [0, 0] => Symbol: a
240
+ # [0, 1] => String: b
241
+ # [1, 0] => Integer: 3
242
+ # [1, 1] => TrueClass: true
243
+ # @yieldparam coords [Array<Integer>] the coordinates of the cell in a 2-item array where:
244
+ # # - The first item is the row index.
245
+ # # - The second item is the column index.
246
+ # @yieldparam value [Object] the value stored within the cell
247
+ # @return [self]
248
+ def each_cell
249
+ return to_enum(__callee__) unless block_given?
250
+ @grid.each_with_index do |row, r_index|
251
+ row.each_with_index do |cell, c_index|
252
+ yield [[r_index, c_index], cell]
253
+ end
254
+ end
255
+ self
256
+ end
257
+
258
+ private
259
+
260
+ def locate_value(element)
261
+ row = @grid.index { |row| row.include?(element) }
262
+ return nil if row.nil?
263
+ column = @grid[row].index(element)
264
+ [row, column]
265
+ end
129
266
  end
@@ -1,3 +1,3 @@
1
1
  module AocRbHelpers
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aoc_rb_helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Pascoe
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-12-05 00:00:00.000000000 Z
11
+ date: 2024-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aoc_rb