aoc_rb_helpers 0.0.1 → 0.0.2

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