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 +4 -4
- data/CHANGELOG.md +12 -1
- data/Gemfile +2 -0
- data/README.md +39 -0
- data/aoc_rb_helpers.gemspec +2 -2
- data/lib/aoc_rb_helpers/aoc_input.rb +53 -4
- data/lib/aoc_rb_helpers/dot_matrix.rb +256 -0
- data/lib/aoc_rb_helpers/version.rb +1 -1
- metadata +11 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e9049a2637e249afd1d2670f1b4ca3616aa21ef94ae10efb271178693ff16f63
|
4
|
+
data.tar.gz: 485a04d7594ef25fbec3fb2ca19060c8f5699a30fb0845ec9c985a899aae5be4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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
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
|
+
```
|
data/aoc_rb_helpers.gemspec
CHANGED
@@ -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["
|
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
|
-
|
5
|
-
|
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
|
-
|
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(
|
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
|
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.
|
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:
|
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:
|
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
|
-
|
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: []
|