aoc_rb_helpers 0.0.1 → 0.0.2

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: 15a53c3fd46773e8f18a1e5d0e9d76ba14a42f908c244b5628fd9c913f199739
4
+ data.tar.gz: c500c60c483e56f472b5b254428c805d44aec5d253f03377c7e65e2592e38d07
5
5
  SHA512:
6
- metadata.gz: c03ddeaafa12bb07fd9c87a2d23f11d18edf593ba3ea4390dbea32d5322d0e77e1d0662e08062729f978c1cfc4e77c7437f3b9a06bb46b61bb3a876865577dbd
7
- data.tar.gz: 204a9d87b4eb34b6b9ae37875d2e2b22235e585180522eae6a25dd100f326e682a3d68e0967ea9bfc258ab39fa53376322c24457b68093718a9ff93a0e26fdc5
6
+ metadata.gz: 117da557cc26d663671fa7ff39b4557e730da2d57484c573631750ad5d7d8733c96d8c3a6841d6aa48db3eecbdcaa1800d1244bd3b3587175a08745bc93ad912
7
+ data.tar.gz: a6bdd6ae05609d22bb1d486ea73aa5b62ffa246a6677e76573e4b1957cf5df2f9db896a4b3ab7ec31116aa0e696b6065fbc399816c5b213d9d9d06ebdebdbbf9
data/CHANGELOG.md CHANGED
@@ -7,11 +7,16 @@ 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.2]
11
+ ### Added
12
+ - DotMatrix class for decoding printed puzzle output
13
+
10
14
  ## [0.0.1]
11
15
  Initial release.
12
16
 
13
17
  ### Added
14
18
  - Created `AocInput` class with initial helper methods
15
19
 
16
- [Unreleased]: https://github.com/pacso/aoc_rb_helpers/compare/v0.0.1...HEAD
20
+ [Unreleased]: https://github.com/pacso/aoc_rb_helpers/compare/v0.0.2...HEAD
21
+ [0.0.2]: https://github.com/pacso/aoc_rb_helpers/compare/v0.0.1...v0.0.2
17
22
  [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"
@@ -13,7 +13,6 @@ 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"
17
16
  spec.metadata["changelog_uri"] = "https://github.com/pacso/aoc_rb_helpers/blob/main/CHANGELOG"
18
17
 
19
18
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
@@ -24,5 +23,5 @@ Gem::Specification.new do |spec|
24
23
  spec.require_paths = ["lib"]
25
24
 
26
25
  spec.add_dependency "aoc_rb", "~> 0.2", ">= 0.2.6"
27
- spec.add_dependency "puts_debuggerer"
26
+ spec.add_dependency "puts_debuggerer", '~> 1.0', '>= 1.0.1'
28
27
  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,234 @@
1
+ # frozen_string_literal: true
2
+
3
+ class DotMatrix
4
+ CHAR_WIDTH = 5
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
+ e: [
31
+ "XXXX ",
32
+ "X ",
33
+ "XXX ",
34
+ "X ",
35
+ "X ",
36
+ "XXXX "
37
+ ],
38
+ f: [
39
+ "XXXX ",
40
+ "X ",
41
+ "XXX ",
42
+ "X ",
43
+ "X ",
44
+ "X "
45
+ ],
46
+ g: [
47
+ " XX ",
48
+ "X X ",
49
+ "X ",
50
+ "X XX ",
51
+ "X X ",
52
+ " XXX "
53
+ ],
54
+ h: [
55
+ "X X ",
56
+ "X X ",
57
+ "XXXX ",
58
+ "X X ",
59
+ "X X ",
60
+ "X X ",
61
+ ],
62
+ j: [
63
+ " XX ",
64
+ " X ",
65
+ " X ",
66
+ " X ",
67
+ "X X ",
68
+ " XX ",
69
+ ],
70
+ k: [
71
+ "X X ",
72
+ "X X ",
73
+ "XX ",
74
+ "X X ",
75
+ "X X ",
76
+ "X X ",
77
+ ],
78
+ l: [
79
+ "X ",
80
+ "X ",
81
+ "X ",
82
+ "X ",
83
+ "X ",
84
+ "XXXX ",
85
+ ],
86
+ o: [
87
+ " XX ",
88
+ "X X ",
89
+ "X X ",
90
+ "X X ",
91
+ "X X ",
92
+ " XX "
93
+ ],
94
+ p: [
95
+ "XXX ",
96
+ "X X ",
97
+ "X X ",
98
+ "XXX ",
99
+ "X ",
100
+ "X ",
101
+ ],
102
+ r: [
103
+ "XXX ",
104
+ "X X ",
105
+ "X X ",
106
+ "XXX ",
107
+ "X X ",
108
+ "X X ",
109
+ ],
110
+ s: [
111
+ " XXX ",
112
+ "X ",
113
+ "X ",
114
+ " XX ",
115
+ " X ",
116
+ "XXX ",
117
+ ],
118
+ u: [
119
+ "X X ",
120
+ "X X ",
121
+ "X X ",
122
+ "X X ",
123
+ "X X ",
124
+ " XX ",
125
+ ],
126
+ y: [
127
+ "X X",
128
+ "X X",
129
+ " X X ",
130
+ " X ",
131
+ " X ",
132
+ " X "
133
+ ],
134
+ z: [
135
+ "XXXX ",
136
+ " X ",
137
+ " X ",
138
+ " X ",
139
+ "X ",
140
+ "XXXX ",
141
+ ]
142
+ }
143
+
144
+ # Returns the decoded input using the specified characters for printed text (on) and whitespace (off).
145
+ # @param [Array<Array<String>>] input a two-dimensional array of characters
146
+ # @param on [String] specifies the character representing the "on" state, or printed text
147
+ # @param off [String] specifies the character representing the "off" state, or whitespace
148
+ # @return [String] the decoded string
149
+ def self.decode(input, on: "X", off: " ")
150
+ new(input, on, off).to_s
151
+ end
152
+
153
+ # @param [Array<Array<String>>] input a two-dimensional array of characters
154
+ # @param on [String] specifies the character representing the "on" state, or printed text
155
+ # @param off [String] specifies the character representing the "off" state, or whitespace
156
+ def initialize(input, on = "X", off = " ")
157
+ @input = input
158
+ @on = on
159
+ @off = off
160
+ end
161
+
162
+ # Prints the input array to STDOUT and returns self.
163
+ # @return [DotMatrix] self
164
+ def print(input = @input)
165
+ input.each do |row|
166
+ puts row.is_a?(String) ? row : row.join
167
+ end
168
+ self
169
+ end
170
+
171
+ # Prints the decoded input to STDOUT and returns self.
172
+ # @return [DotMatrix] self
173
+ def print_decoded
174
+ puts to_s
175
+ self
176
+ end
177
+
178
+ # Returns the decoded input.
179
+ # @return [String] the decoded input
180
+ def to_s
181
+ (0...max_chars).map do |char_index|
182
+ begin
183
+ char_map = printable_content.map do |row|
184
+ row[char_offset(char_index)...char_offset(char_index + 1)].join
185
+ end
186
+
187
+ unless @on == "X" && @off == " "
188
+ new_map = []
189
+ char_map.each do |row|
190
+ row_chars = []
191
+ row.chars.each do |cell|
192
+ row_chars.push(cell == @on ? "X" : " ")
193
+ end
194
+ new_map.push(row_chars.join)
195
+ end
196
+ char_map = new_map
197
+ end
198
+
199
+ DICTIONARY.find { |_, map| map == char_map }[0].to_s.upcase
200
+ rescue NoMethodError
201
+ puts "ERROR: Missing character in dictionary:\n\n"
202
+ print(char_map)
203
+ puts "\nReverting to ASCII:\n\n"
204
+ print
205
+ break
206
+ end
207
+ end.join
208
+ end
209
+
210
+ private
211
+ def char_offset(index)
212
+ index * CHAR_WIDTH
213
+ end
214
+
215
+ def printable_range(row)
216
+ row[first_position..last_position]
217
+ end
218
+
219
+ def printable_content
220
+ @input.map { |row| printable_range(row) }
221
+ end
222
+
223
+ def first_position
224
+ @input.map { |row| row.index { |dot| dot != ' ' } }.min
225
+ end
226
+
227
+ def last_position
228
+ @input.map { |row| row.rindex { |dot| dot != ' ' } }.max + 1
229
+ end
230
+
231
+ def max_chars
232
+ printable_content.first.length / CHAR_WIDTH
233
+ end
234
+ end
@@ -1,3 +1,3 @@
1
1
  module AocRbHelpers
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
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.2
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,6 @@ 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
74
80
  changelog_uri: https://github.com/pacso/aoc_rb_helpers/blob/main/CHANGELOG
75
81
  post_install_message:
76
82
  rdoc_options: []