aoc_rb_helpers 0.0.1 → 0.0.3

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: 87b50db9a3acbc96dbf8cb70e3a3fa2f3e1341166616c3e9c29a53b6d9994201
4
- data.tar.gz: 109fc954d7f8ec4d396ee76f51f22bb0289aed2ee68c2e605898c7204049c079
3
+ metadata.gz: e9049a2637e249afd1d2670f1b4ca3616aa21ef94ae10efb271178693ff16f63
4
+ data.tar.gz: 485a04d7594ef25fbec3fb2ca19060c8f5699a30fb0845ec9c985a899aae5be4
5
5
  SHA512:
6
- metadata.gz: c03ddeaafa12bb07fd9c87a2d23f11d18edf593ba3ea4390dbea32d5322d0e77e1d0662e08062729f978c1cfc4e77c7437f3b9a06bb46b61bb3a876865577dbd
7
- data.tar.gz: 204a9d87b4eb34b6b9ae37875d2e2b22235e585180522eae6a25dd100f326e682a3d68e0967ea9bfc258ab39fa53376322c24457b68093718a9ff93a0e26fdc5
6
+ metadata.gz: 6343e8180d5ab30baecad403c7765b4a666562a713154541c70ee6a602ecaa3253c08a25f89db76d36e4e86371901564b34eb7ba779fbbaa2e011cb543edf10a
7
+ data.tar.gz: dade32999ee76bbda52f4615cad719ab2dc4ab2209dccf88b6756b0f63d125d7dfe40b76d61e85245c599b472b29e426c5dd110b91c5c3eb46bd8ffd1ab96f84
data/CHANGELOG.md CHANGED
@@ -7,11 +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.3]
11
+ ### Added
12
+ - Characters `I` and `T` now supported by DotMatrix
13
+ - Updated README with links to documentation
14
+ - Added documentation link to gemspec
15
+
16
+ ## [0.0.2]
17
+ ### Added
18
+ - DotMatrix class for decoding printed puzzle output
19
+
10
20
  ## [0.0.1]
11
21
  Initial release.
12
22
 
13
23
  ### Added
14
24
  - Created `AocInput` class with initial helper methods
15
25
 
16
- [Unreleased]: https://github.com/pacso/aoc_rb_helpers/compare/v0.0.1...HEAD
26
+ [Unreleased]: https://github.com/pacso/aoc_rb_helpers/compare/v0.0.2...HEAD
27
+ [0.0.2]: https://github.com/pacso/aoc_rb_helpers/compare/v0.0.1...v0.0.2
17
28
  [0.0.1]: https://github.com/pacso/aoc_rb_helpers
data/Gemfile CHANGED
@@ -5,3 +5,5 @@ gemspec
5
5
 
6
6
  gem "rake", "~> 13.0"
7
7
  gem "puts_debuggerer"
8
+ gem "yard"
9
+ gem "webrick"
data/README.md CHANGED
@@ -35,6 +35,29 @@ pd some_object
35
35
 
36
36
  You can read more on how you can use `pd` in their [README](https://github.com/AndyObtiva/puts_debuggerer/blob/master/README.md).
37
37
 
38
+ ## Provided Helper Classes
39
+
40
+ All documentation is available here - https://rubydoc.info/github/pacso/aoc_rb_helpers.
41
+
42
+ The provided helper classes are as follows:
43
+
44
+ ### [AocInput](https://rubydoc.info/github/pacso/aoc_rb_helpers/AocInput)
45
+ Provides input manipulation helper methods. Methods are chainable, and directly modify the parsed view of the input data within the `@data` instance variable.
46
+
47
+ ### [DotMatrix](https://rubydoc.info/github/pacso/aoc_rb_helpers/DotMatrix)
48
+ Parses and decodes ASCII art text from puzzles. Can output to STDOUT or return the result to your code.
49
+
50
+ Will turn an input like:
51
+ ```ruby
52
+ XX XXXX X XXXX X XX X XXXXX XX XXX
53
+ X X X X X X X X X XX X X X
54
+ X XXX X XXX X X X X X XXX X X
55
+ X X X X X X X X X X XX
56
+ X X X X X X X X X X X X X
57
+ XX X XXXX XXXX XXXX XX X X XX XXX
58
+ ```
59
+ Into the string `CFLELOYFCS`.
60
+
38
61
  ## Examples
39
62
 
40
63
  Below are some examples of how you can use the features of this gem.
@@ -71,3 +94,19 @@ module Year2024
71
94
  end
72
95
  end
73
96
  ```
97
+
98
+ ### Decoding printed text
99
+
100
+ ```ruby
101
+ text_input = <<~EOF
102
+ X X XXXX X X XX
103
+ X X X X X X X
104
+ XXXX XXX X X X X
105
+ X X X X X X X
106
+ X X X X X X X
107
+ X X XXXX XXXX XXXX XX
108
+ EOF
109
+
110
+ input_array = text_input.lines(chomp: true).map(&:chars)
111
+ DotMatrix.decode(input_array) # returns the string "HELLO"
112
+ ```
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
13
13
  spec.required_ruby_version = Gem::Requirement.new("~> 3.1", ">= 3.1.0")
14
14
 
15
15
  spec.metadata["homepage_uri"] = spec.homepage
16
- spec.metadata["source_code_uri"] = "https://github.com/pacso/aoc_rb_helpers"
16
+ spec.metadata["documentation_uri"] = "https://rubydoc.info/github/pacso/aoc_rb_helpers"
17
17
  spec.metadata["changelog_uri"] = "https://github.com/pacso/aoc_rb_helpers/blob/main/CHANGELOG"
18
18
 
19
19
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
@@ -24,5 +24,5 @@ Gem::Specification.new do |spec|
24
24
  spec.require_paths = ["lib"]
25
25
 
26
26
  spec.add_dependency "aoc_rb", "~> 0.2", ">= 0.2.6"
27
- spec.add_dependency "puts_debuggerer"
27
+ spec.add_dependency "puts_debuggerer", '~> 1.0', '>= 1.0.1'
28
28
  end
@@ -1,35 +1,79 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Provides input manipulation helper methods.
4
+ # Methods are chainable, and directly modify the parsed view of the input data within the @data instance variable.
5
+ #
6
+ # Once manipulated as required, the input is accessable from #data
3
7
  class AocInput
4
- def initialize(input)
5
- @raw_input = input
8
+ # Returns a new AocInput initialized with the given puzzle input.
9
+ #
10
+ # @param puzzle_input [String] the puzzle input as a single string with embedded newline characters
11
+ def initialize(puzzle_input)
12
+ @raw_input = puzzle_input
6
13
  configure_method_access
7
14
  end
8
15
 
16
+ # Returns the parsed puzzle input.
17
+ #
18
+ # If the data has not been parsed yet, it defaults to the raw input provided in {initialize}.
19
+ #
20
+ # @return [Object] the parsed puzzle input
9
21
  def data
10
22
  @data ||= @raw_input
11
23
  end
12
24
 
25
+ # Splits the input string into an array of lines.
26
+ #
27
+ # This method processes `@data` by splitting the input string into multiple lines,
28
+ # removing trailing newline characters. It modifies `@data` directly and returns `self`
29
+ # to enable method chaining.
30
+ #
31
+ # @return [AocInput] self
13
32
  def multiple_lines
14
33
  @data = data.lines(chomp: true)
15
34
  allow(:columns_of_numbers)
35
+ revoke(:multiple_lines)
16
36
  self
17
37
  end
18
38
 
19
- def columns_of_numbers(divider = nil)
39
+ # Splits each string in the data array into an array of numbers.
40
+ #
41
+ # This method processes `@data` by splitting each string in the array using the specified delimiter,
42
+ # then converting each resulting element to an integer. It modifies `@data` directly and enables
43
+ # chaining by returning `self`.
44
+ #
45
+ # @param delimiter [String, nil] the delimiter to be passed to `String#split`
46
+ # @raise [RuntimeError] if {#multiple_lines} has not been called
47
+ # @return [AocInput] self
48
+ def columns_of_numbers(delimiter = nil)
20
49
  can_call?(:columns_of_numbers, "call .multiple_lines first")
21
- @data = data.map { |line| line.split(divider).map(&:to_i) }
50
+ @data = data.map { |line| line.split(delimiter).map(&:to_i) }
22
51
  allow(:sort_arrays)
23
52
  allow(:transpose)
53
+ revoke(:columns_of_numbers)
24
54
  self
25
55
  end
26
56
 
57
+ # Transposes the data array.
58
+ #
59
+ # This method can only be called after {columns_of_numbers}.
60
+ # It directly modifies `@data` by transposing it and returns `self` to allow method chaining.
61
+ #
62
+ # @raise [RuntimeError] if {columns_of_numbers} has not been called.
63
+ # @return [AocInput] self
27
64
  def transpose
28
65
  can_call?(:transpose, "call .columns_of_numbers first")
29
66
  @data = data.transpose
30
67
  self
31
68
  end
32
69
 
70
+ # Sorts each array within the `@data` array.
71
+ #
72
+ # This method processes `@data` by sorting each nested array in ascending order.
73
+ # It directly modifies `@data` and returns `self` to enable method chaining.
74
+ #
75
+ # @raise [RuntimeError] if {#columns_of_numbers} has not been called
76
+ # @return [AocInput] self
33
77
  def sort_arrays
34
78
  can_call?(:sort_arrays, "call .columns_of_numbers first")
35
79
  @data = data.map { |ary| ary.sort }
@@ -40,6 +84,7 @@ class AocInput
40
84
  def configure_method_access
41
85
  @can_call = {
42
86
  columns_of_numbers: false,
87
+ multiple_lines: true,
43
88
  sort_arrays: false,
44
89
  transpose: false
45
90
  }
@@ -49,6 +94,10 @@ class AocInput
49
94
  @can_call[method_name.to_sym] = true
50
95
  end
51
96
 
97
+ def revoke(method_name)
98
+ @can_call[method_name.to_sym] = false
99
+ end
100
+
52
101
  def can_call?(method_name, msg = "operation not permitted")
53
102
  raise RuntimeError, msg unless @can_call[method_name.to_sym]
54
103
  end
@@ -0,0 +1,256 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Parses and decodes ASCII art text from puzzles. Can output to STDOUT or return the result to your code.
4
+ class DotMatrix
5
+ DICTIONARY = {
6
+ a: [
7
+ " XX ",
8
+ "X X",
9
+ "X X",
10
+ "XXXX",
11
+ "X X",
12
+ "X X"
13
+ ],
14
+ b: [
15
+ "XXX ",
16
+ "X X",
17
+ "XXX ",
18
+ "X X",
19
+ "X X",
20
+ "XXX "
21
+ ],
22
+ c: [
23
+ " XX ",
24
+ "X X",
25
+ "X ",
26
+ "X ",
27
+ "X X",
28
+ " XX "
29
+ ],
30
+ d: [
31
+ "XXX ",
32
+ "X X",
33
+ "X X",
34
+ "X X",
35
+ "X X",
36
+ "XXX "
37
+ ],
38
+ e: [
39
+ "XXXX",
40
+ "X ",
41
+ "XXX ",
42
+ "X ",
43
+ "X ",
44
+ "XXXX"
45
+ ],
46
+ f: [
47
+ "XXXX",
48
+ "X ",
49
+ "XXX ",
50
+ "X ",
51
+ "X ",
52
+ "X "
53
+ ],
54
+ g: [
55
+ " XX ",
56
+ "X X",
57
+ "X ",
58
+ "X XX",
59
+ "X X",
60
+ " XXX"
61
+ ],
62
+ h: [
63
+ "X X",
64
+ "X X",
65
+ "XXXX",
66
+ "X X",
67
+ "X X",
68
+ "X X",
69
+ ],
70
+ i: [
71
+ "XXX",
72
+ " X ",
73
+ " X ",
74
+ " X ",
75
+ " X ",
76
+ "XXX"
77
+ ],
78
+ j: [
79
+ " XX",
80
+ " X",
81
+ " X",
82
+ " X",
83
+ "X X",
84
+ " XX ",
85
+ ],
86
+ k: [
87
+ "X X",
88
+ "X X ",
89
+ "XX ",
90
+ "X X ",
91
+ "X X ",
92
+ "X X",
93
+ ],
94
+ l: [
95
+ "X ",
96
+ "X ",
97
+ "X ",
98
+ "X ",
99
+ "X ",
100
+ "XXXX",
101
+ ],
102
+ o: [
103
+ " XX ",
104
+ "X X",
105
+ "X X",
106
+ "X X",
107
+ "X X",
108
+ " XX "
109
+ ],
110
+ p: [
111
+ "XXX ",
112
+ "X X",
113
+ "X X",
114
+ "XXX ",
115
+ "X ",
116
+ "X ",
117
+ ],
118
+ r: [
119
+ "XXX ",
120
+ "X X",
121
+ "X X",
122
+ "XXX ",
123
+ "X X ",
124
+ "X X",
125
+ ],
126
+ s: [
127
+ " XXX",
128
+ "X ",
129
+ "X ",
130
+ " XX ",
131
+ " X",
132
+ "XXX ",
133
+ ],
134
+ t: [
135
+ "XXX",
136
+ " X ",
137
+ " X ",
138
+ " X ",
139
+ " X ",
140
+ " X "
141
+ ],
142
+ u: [
143
+ "X X",
144
+ "X X",
145
+ "X X",
146
+ "X X",
147
+ "X X",
148
+ " XX ",
149
+ ],
150
+ y: [
151
+ "X X",
152
+ "X X",
153
+ " X X ",
154
+ " X ",
155
+ " X ",
156
+ " X "
157
+ ],
158
+ z: [
159
+ "XXXX",
160
+ " X",
161
+ " X ",
162
+ " X ",
163
+ "X ",
164
+ "XXXX",
165
+ ]
166
+ }
167
+
168
+ # Returns the decoded input using the specified characters for printed text (on) and whitespace (off).
169
+ # @param [Array<Array<String>>] input a two-dimensional array of characters
170
+ # @param on [String] specifies the character representing the "on" state, or printed text
171
+ # @param off [String] specifies the character representing the "off" state, or whitespace
172
+ # @return [String] the decoded string
173
+ def self.decode(input, on: "X", off: " ")
174
+ new(input, on, off).to_s
175
+ end
176
+
177
+ # @param [Array<Array<String>>] input a two-dimensional array of characters
178
+ # @param on [String] specifies the character representing the "on" state, or printed text
179
+ # @param off [String] specifies the character representing the "off" state, or whitespace
180
+ def initialize(input, on = "X", off = " ")
181
+ @input = input
182
+ @on = on
183
+ @off = off
184
+
185
+ convert_characters
186
+ end
187
+
188
+ # Prints the input array to STDOUT and returns self.
189
+ # @return [DotMatrix] self
190
+ def print(input = @input)
191
+ input.each do |row|
192
+ puts row.is_a?(String) ? row : row.join
193
+ end
194
+ self
195
+ end
196
+
197
+ # Prints the decoded input to STDOUT and returns self.
198
+ # @return [DotMatrix] self
199
+ def print_decoded
200
+ puts to_s
201
+ self
202
+ end
203
+
204
+ # Returns the decoded input.
205
+ # @return [String] the decoded input
206
+ def to_s
207
+ cursor = 0
208
+ decoded = ""
209
+ while cursor < max_cursor
210
+ begin
211
+ cursor += 1 while @input.all? { |row| row[cursor] == ' ' }
212
+ cursor_end = cursor_range(cursor)
213
+ char_map = @input.map do |row|
214
+ row[cursor...cursor_end].join
215
+ end
216
+ cursor = cursor_end
217
+
218
+ decoded += DICTIONARY.find { |_, map| map == char_map }[0].to_s.upcase
219
+ rescue NoMethodError
220
+ puts "ERROR: Missing character in dictionary:\n\n"
221
+ print(char_map)
222
+ puts "\nReverting to ASCII:\n\n"
223
+ print
224
+ break
225
+ end
226
+ end
227
+
228
+ decoded
229
+ end
230
+
231
+ private
232
+
233
+ def convert_characters
234
+ unless @on == "X" && @off == " "
235
+ @input = @input.map do |row|
236
+ row.map do |cell|
237
+ cell == @on ? "X" : " "
238
+ end
239
+ end
240
+ end
241
+ end
242
+
243
+ def cursor_range(cursor)
244
+ c = cursor
245
+ c += 1 while @input.any? { |row| row[c] != ' ' } && c - cursor < max_cursor_range
246
+ c
247
+ end
248
+
249
+ def max_cursor
250
+ @input.first.length - 4
251
+ end
252
+
253
+ def max_cursor_range
254
+ DICTIONARY.values.map { |v| v.first.length }.max
255
+ end
256
+ end
@@ -1,3 +1,3 @@
1
1
  module AocRbHelpers
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.3"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aoc_rb_helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Pascoe
@@ -34,16 +34,22 @@ dependencies:
34
34
  name: puts_debuggerer
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.0'
37
40
  - - ">="
38
41
  - !ruby/object:Gem::Version
39
- version: '0'
42
+ version: 1.0.1
40
43
  type: :runtime
41
44
  prerelease: false
42
45
  version_requirements: !ruby/object:Gem::Requirement
43
46
  requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '1.0'
44
50
  - - ">="
45
51
  - !ruby/object:Gem::Version
46
- version: '0'
52
+ version: 1.0.1
47
53
  description: Enhances the aoc_rb gem with tools for parsing puzzle input, and handling
48
54
  various data manipulations within Advent of Code puzzle solutions.
49
55
  email:
@@ -63,6 +69,7 @@ files:
63
69
  - aoc_rb_helpers.gemspec
64
70
  - lib/aoc_rb_helpers.rb
65
71
  - lib/aoc_rb_helpers/aoc_input.rb
72
+ - lib/aoc_rb_helpers/dot_matrix.rb
66
73
  - lib/aoc_rb_helpers/solution/input_handling.rb
67
74
  - lib/aoc_rb_helpers/version.rb
68
75
  homepage: https://github.com/pacso/aoc_rb_helpers
@@ -70,7 +77,7 @@ licenses:
70
77
  - MIT
71
78
  metadata:
72
79
  homepage_uri: https://github.com/pacso/aoc_rb_helpers
73
- source_code_uri: https://github.com/pacso/aoc_rb_helpers
80
+ documentation_uri: https://rubydoc.info/github/pacso/aoc_rb_helpers
74
81
  changelog_uri: https://github.com/pacso/aoc_rb_helpers/blob/main/CHANGELOG
75
82
  post_install_message:
76
83
  rdoc_options: []