rambling-trie 2.2.1 → 2.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +5 -1
- data/LICENSE +1 -1
- data/README.md +37 -21
- data/lib/rambling/trie/comparable.rb +2 -2
- data/lib/rambling/trie/compressible.rb +3 -3
- data/lib/rambling/trie/configuration/properties.rb +10 -9
- data/lib/rambling/trie/configuration/provider_collection.rb +17 -15
- data/lib/rambling/trie/container.rb +18 -20
- data/lib/rambling/trie/enumerable.rb +4 -1
- data/lib/rambling/trie/nodes/compressed.rb +3 -3
- data/lib/rambling/trie/nodes/node.rb +18 -18
- data/lib/rambling/trie/nodes/raw.rb +2 -2
- data/lib/rambling/trie/readers/plain_text.rb +9 -4
- data/lib/rambling/trie/readers/reader.rb +21 -0
- data/lib/rambling/trie/readers.rb +1 -1
- data/lib/rambling/trie/serializers/file.rb +1 -1
- data/lib/rambling/trie/serializers/marshal.rb +6 -5
- data/lib/rambling/trie/serializers/serializer.rb +27 -0
- data/lib/rambling/trie/serializers/yaml.rb +7 -7
- data/lib/rambling/trie/serializers/zip.rb +9 -5
- data/lib/rambling/trie/serializers.rb +1 -1
- data/lib/rambling/trie/stringifyable.rb +1 -1
- data/lib/rambling/trie/version.rb +1 -1
- data/lib/rambling/trie.rb +12 -10
- data/rambling-trie.gemspec +8 -4
- data/spec/integration/rambling/trie_spec.rb +13 -16
- data/spec/lib/rambling/trie/comparable_spec.rb +29 -39
- data/spec/lib/rambling/trie/compressor_spec.rb +17 -14
- data/spec/lib/rambling/trie/configuration/properties_spec.rb +25 -7
- data/spec/lib/rambling/trie/configuration/provider_collection_spec.rb +42 -14
- data/spec/lib/rambling/trie/container_spec.rb +200 -325
- data/spec/lib/rambling/trie/enumerable_spec.rb +18 -10
- data/spec/lib/rambling/trie/inspectable_spec.rb +9 -3
- data/spec/lib/rambling/trie/nodes/node_spec.rb +1 -1
- data/spec/lib/rambling/trie/nodes/raw_spec.rb +26 -23
- data/spec/lib/rambling/trie/readers/plain_text_spec.rb +11 -1
- data/spec/lib/rambling/trie/readers/reader_spec.rb +14 -0
- data/spec/lib/rambling/trie/serializers/file_spec.rb +1 -3
- data/spec/lib/rambling/trie/serializers/marshal_spec.rb +1 -3
- data/spec/lib/rambling/trie/serializers/serializer_spec.rb +21 -0
- data/spec/lib/rambling/trie/serializers/yaml_spec.rb +1 -3
- data/spec/lib/rambling/trie/serializers/zip_spec.rb +24 -16
- data/spec/lib/rambling/trie/stringifyable_spec.rb +17 -13
- data/spec/lib/rambling/trie_spec.rb +106 -44
- data/spec/spec_helper.rb +14 -9
- data/spec/support/shared_examples/a_compressible_trie.rb +9 -3
- data/spec/support/shared_examples/a_container_partial_word.rb +17 -0
- data/spec/support/shared_examples/a_container_scan.rb +14 -0
- data/spec/support/shared_examples/a_container_word.rb +43 -0
- data/spec/support/shared_examples/a_container_words_within.rb +44 -0
- data/spec/support/shared_examples/a_serializable_trie.rb +4 -8
- data/spec/support/shared_examples/a_serializer.rb +36 -13
- data/spec/support/shared_examples/a_trie_data_structure.rb +24 -10
- data/spec/support/shared_examples/a_trie_node.rb +19 -12
- data/spec/support/shared_examples/a_trie_node_implementation.rb +40 -43
- metadata +26 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3af7f8936c101be83262b9535524bdcd3381bb76b857e7a44f331c932c67afb4
|
4
|
+
data.tar.gz: e1b9dfc8f88822404c82f95b3fac6a376d3433d15535e8fc0dd454b4669f9e52
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8bc211404f2a209892aa7de20f20ce5b61f481f117f4ac2f3c45cceaf7076e690229487c7f2dd4613d5725fdf38e4a616efe082b27d4055c359f5801457f704d
|
7
|
+
data.tar.gz: 21cb664d6abccbc565fa8c2441c54c18d3ab8a4ccf8ae2457f4671b6b2b579ccd4893a400b3756af82bc261afa8c804db352bf68b6aa0105ab91396b90e1f2be
|
data/Gemfile
CHANGED
@@ -16,11 +16,15 @@ group :development do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
group :test do
|
19
|
-
gem '
|
19
|
+
gem 'coveralls_reborn', '~> 0.27.0', require: false
|
20
|
+
gem 'rspec_junit_formatter'
|
20
21
|
gem 'simplecov', require: false
|
21
22
|
end
|
22
23
|
|
23
24
|
group :local do
|
24
25
|
gem 'guard-rspec'
|
25
26
|
gem 'rubocop', require: false
|
27
|
+
gem 'rubocop-performance', require: false
|
28
|
+
gem 'rubocop-rake', require: false
|
29
|
+
gem 'rubocop-rspec', require: false
|
26
30
|
end
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,16 @@
|
|
1
1
|
# Rambling Trie
|
2
2
|
|
3
|
-
[![Gem Version][badge_fury_badge]][badge_fury_link]
|
3
|
+
[![Gem Version][badge_fury_badge]][badge_fury_link]
|
4
|
+
[![Downloads][downloads_badge]][downloads_link]
|
5
|
+
[![License][license_badge]][license_link]
|
6
|
+
|
7
|
+
[![Build Status][github_action_build_badge]][github_action_build_link]
|
8
|
+
[![Coverage Status][coveralls_badge]][coveralls_link]
|
9
|
+
[![Documentation Status][inch_ci_badge]][rubydoc]
|
10
|
+
[![CodeQL Status][github_action_codeql_badge]][github_action_codeql_link]
|
11
|
+
|
12
|
+
[![Code Climate Grade][code_climate_grade_badge]][code_climate_link]
|
13
|
+
[![Code Climate Issue Count][code_climate_issues_badge]][code_climate_link]
|
4
14
|
|
5
15
|
The Rambling Trie is a Ruby implementation of the [trie data structure][trie_wiki], which includes compression abilities and is designed to be very fast to traverse.
|
6
16
|
|
@@ -10,7 +20,7 @@ The Rambling Trie is a Ruby implementation of the [trie data structure][trie_wik
|
|
10
20
|
|
11
21
|
You will need:
|
12
22
|
|
13
|
-
* Ruby 2.
|
23
|
+
* Ruby 2.7.0 or up
|
14
24
|
* RubyGems
|
15
25
|
|
16
26
|
See [RVM][rvm], [rbenv][rbenv] or [chruby][chruby] for more information on how to manage Ruby versions.
|
@@ -167,7 +177,7 @@ Rambling::Trie.dump trie, '/path/to/file'
|
|
167
177
|
Then, when you need to use a trie next time, you don't have to create a new one with all the necessary words. Rather, you can retrieve a previously stored one with `.load` like this:
|
168
178
|
|
169
179
|
``` ruby
|
170
|
-
trie = Rambling::Trie.load
|
180
|
+
trie = Rambling::Trie.load '/path/to/file'
|
171
181
|
```
|
172
182
|
|
173
183
|
#### Supported formats
|
@@ -197,7 +207,7 @@ Then, you can load contents form a `.zip` file like this:
|
|
197
207
|
|
198
208
|
``` ruby
|
199
209
|
require 'zip'
|
200
|
-
trie = Rambling::Trie.load
|
210
|
+
trie = Rambling::Trie.load '/path/to/file.zip'
|
201
211
|
```
|
202
212
|
|
203
213
|
> For `.zip` files, the format is also determined automatically based on the
|
@@ -242,20 +252,22 @@ You can find further API documentation on the autogenerated [rambling-trie gem R
|
|
242
252
|
|
243
253
|
The Rambling Trie has been tested with the following Ruby versions:
|
244
254
|
|
255
|
+
* 3.2.x
|
256
|
+
* 3.1.x
|
245
257
|
* 3.0.x
|
246
258
|
* 2.7.x
|
247
|
-
* 2.6.x
|
248
|
-
* 2.5.x
|
249
259
|
|
250
260
|
**No longer supported**:
|
251
261
|
|
262
|
+
* 2.6.x (EOL'ed)
|
263
|
+
* 2.5.x (EOL'ed)
|
252
264
|
* 2.4.x (EOL'ed)
|
253
265
|
* 2.3.x (EOL'ed)
|
254
|
-
* 2.2.x
|
255
|
-
* 2.1.x
|
256
|
-
* 2.0.x
|
257
|
-
* 1.9.x
|
258
|
-
* 1.8.x
|
266
|
+
* 2.2.x (EOL'ed)
|
267
|
+
* 2.1.x (EOL'ed)
|
268
|
+
* 2.0.x (EOL'ed)
|
269
|
+
* 1.9.x (EOL'ed)
|
270
|
+
* 1.8.x (EOL'ed)
|
259
271
|
|
260
272
|
## Contributing to Rambling Trie
|
261
273
|
|
@@ -263,7 +275,7 @@ Take a look at the [contributing guide][rambling_trie_contributing_guide] to get
|
|
263
275
|
|
264
276
|
## License and copyright
|
265
277
|
|
266
|
-
Copyright (c) 2012-
|
278
|
+
Copyright (c) 2012-2023 Edgar González
|
267
279
|
|
268
280
|
MIT License
|
269
281
|
|
@@ -273,21 +285,27 @@ The above copyright notice and this permission notice shall be included in all c
|
|
273
285
|
|
274
286
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
275
287
|
|
276
|
-
[badge_fury_badge]: https://badge.fury.io/rb/rambling-trie.svg
|
288
|
+
[badge_fury_badge]: https://badge.fury.io/rb/rambling-trie.svg?version=2.3.0
|
277
289
|
[badge_fury_link]: https://badge.fury.io/rb/rambling-trie
|
278
290
|
[chruby]: https://github.com/postmodern/chruby
|
279
|
-
[
|
280
|
-
[
|
291
|
+
[code_climate_grade_badge]: https://codeclimate.com/github/gonzedge/rambling-trie/badges/gpa.svg
|
292
|
+
[code_climate_issues_badge]: https://codeclimate.com/github/gonzedge/rambling-trie/badges/issue_count.svg
|
293
|
+
[code_climate_link]: https://codeclimate.com/github/gonzedge/rambling-trie
|
281
294
|
[coveralls_badge]: https://img.shields.io/coveralls/gonzedge/rambling-trie.svg
|
282
295
|
[coveralls_link]: https://coveralls.io/r/gonzedge/rambling-trie
|
296
|
+
[downloads_badge]: https://img.shields.io/gem/dt/rambling-trie.svg
|
297
|
+
[downloads_link]: https://rubygems.org/gems/rambling-trie
|
283
298
|
[gemnasium_badge]: https://gemnasium.com/gonzedge/rambling-trie.svg
|
284
299
|
[gemnasium_link]: https://gemnasium.com/gonzedge/rambling-trie
|
300
|
+
[github_action_build_badge]: https://github.com/gonzedge/rambling-trie/actions/workflows/ruby.yml/badge.svg
|
301
|
+
[github_action_build_link]: https://github.com/gonzedge/rambling-trie/actions/workflows/ruby.yml
|
302
|
+
[github_action_codeql_badge]: https://github.com/gonzedge/rambling-trie/actions/workflows/codeql.yml/badge.svg
|
303
|
+
[github_action_codeql_link]: https://github.com/gonzedge/rambling-trie/actions/workflows/codeql.yml
|
285
304
|
[github_user_gonzedge]: https://github.com/gonzedge
|
286
305
|
[inch_ci_badge]: https://inch-ci.org/github/gonzedge/rambling-trie.svg?branch=master
|
287
|
-
[
|
288
|
-
[license_badge]: https://badges.frapsoft.com/os/mit/mit.svg?v=103
|
306
|
+
[license_badge]: https://img.shields.io/badge/license-MIT-blue.svg
|
289
307
|
[license_link]: https://opensource.org/licenses/mit-license.php
|
290
|
-
[marshal]: https://ruby-doc.org/core-2.
|
308
|
+
[marshal]: https://ruby-doc.org/core-2.7.0/Marshal.html
|
291
309
|
[rambling_trie_configuration]: https://github.com/gonzedge/rambling-trie#configuration
|
292
310
|
[rambling_trie_contributing_guide]: https://github.com/gonzedge/rambling-trie/blob/master/CONTRIBUTING.md
|
293
311
|
[rambling_trie_plain_text_reader]: https://github.com/gonzedge/rambling-trie/blob/master/lib/rambling/trie/readers/plain_text.rb
|
@@ -296,7 +314,5 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|
296
314
|
[rubydoc_github]: http://rubydoc.info/github/gonzedge/rambling-trie
|
297
315
|
[rubyzip]: https://github.com/rubyzip/rubyzip
|
298
316
|
[rvm]: https://rvm.io
|
299
|
-
[travis_ci_badge]: https://travis-ci.com/gonzedge/rambling-trie.svg?branch=master
|
300
|
-
[travis_ci_link]: https://travis-ci.com/github/gonzedge/rambling-trie
|
301
317
|
[trie_wiki]: https://en.wikipedia.org/wiki/Trie
|
302
|
-
[yaml]: https://ruby-doc.org/stdlib-2.
|
318
|
+
[yaml]: https://ruby-doc.org/stdlib-2.7.0/libdoc/yaml/rdoc/YAML.html
|
@@ -6,8 +6,8 @@ module Rambling
|
|
6
6
|
module Comparable
|
7
7
|
# Compares two nodes.
|
8
8
|
# @param [Nodes::Node] other the node to compare against.
|
9
|
-
# @return [Boolean]
|
10
|
-
# {Nodes::Node#children_tree #children_tree} are equal,
|
9
|
+
# @return [Boolean] +true+ if the nodes' {Nodes::Node#letter #letter} and
|
10
|
+
# {Nodes::Node#children_tree #children_tree} are equal, +false+
|
11
11
|
# otherwise.
|
12
12
|
def == other
|
13
13
|
letter == other.letter &&
|
@@ -6,10 +6,10 @@ module Rambling
|
|
6
6
|
module Compressible
|
7
7
|
# Indicates if the current {Rambling::Trie::Nodes::Node Node} can be
|
8
8
|
# compressed or not.
|
9
|
-
# @return [Boolean]
|
10
|
-
# with one child,
|
9
|
+
# @return [Boolean] +true+ for non-{Nodes::Node#terminal? terminal} nodes
|
10
|
+
# with one child, +false+ otherwise.
|
11
11
|
def compressible?
|
12
|
-
!(root? || terminal?) && children_tree.size
|
12
|
+
!(root? || terminal?) && 1 == children_tree.size
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -6,26 +6,26 @@ module Rambling
|
|
6
6
|
# Provides configurable properties for Rambling::Trie.
|
7
7
|
class Properties
|
8
8
|
# The configured {Readers Readers}.
|
9
|
-
# @return [ProviderCollection] the mapping of
|
10
|
-
# Readers}.
|
9
|
+
# @return [ProviderCollection<Readers::Reader>] the mapping of
|
10
|
+
# configured {Readers Readers}.
|
11
11
|
attr_reader :readers
|
12
12
|
|
13
13
|
# The configured {Serializers Serializers}.
|
14
|
-
# @return [ProviderCollection] the mapping of
|
15
|
-
# Serializers}.
|
14
|
+
# @return [ProviderCollection<Serializers::Serializer>] the mapping of
|
15
|
+
# configured {Serializers Serializers}.
|
16
16
|
attr_reader :serializers
|
17
17
|
|
18
18
|
# The configured {Compressor Compressor}.
|
19
19
|
# @return [Compressor] the configured compressor.
|
20
20
|
attr_accessor :compressor
|
21
21
|
|
22
|
-
# The configured root_builder
|
23
|
-
#
|
24
|
-
# @return [Proc<Nodes::Node>] the configured root_builder
|
22
|
+
# The configured +root_builder+, which returns a {Nodes::Node Node}
|
23
|
+
# when called.
|
24
|
+
# @return [Proc<Nodes::Node>] the configured +root_builder+.
|
25
25
|
attr_accessor :root_builder
|
26
26
|
|
27
|
-
# The configured tmp_path
|
28
|
-
# @return [String] the configured tmp_path
|
27
|
+
# The configured +tmp_path+, which will be used for throwaway files.
|
28
|
+
# @return [String] the configured +tmp_path+.
|
29
29
|
attr_accessor :tmp_path
|
30
30
|
|
31
31
|
# Returns a new properties instance.
|
@@ -34,6 +34,7 @@ module Rambling
|
|
34
34
|
end
|
35
35
|
|
36
36
|
# Resets back to default properties.
|
37
|
+
# @return [void]
|
37
38
|
def reset
|
38
39
|
reset_readers
|
39
40
|
reset_serializers
|
@@ -6,7 +6,7 @@ module Rambling
|
|
6
6
|
# Collection of configurable providers.
|
7
7
|
class ProviderCollection
|
8
8
|
# The name of this provider collection.
|
9
|
-
# @return [
|
9
|
+
# @return [Symbol] the name of this provider collection.
|
10
10
|
attr_reader :name
|
11
11
|
|
12
12
|
# @overload default
|
@@ -15,18 +15,18 @@ module Rambling
|
|
15
15
|
# @overload default=(provider)
|
16
16
|
# Sets the default provider. Needs to be one of the configured
|
17
17
|
# providers.
|
18
|
-
# @param [
|
18
|
+
# @param [TProvider] provider the provider to use as default.
|
19
19
|
# @raise [ArgumentError] when the given provider is not in the
|
20
20
|
# provider collection.
|
21
|
-
# @note If no providers have been configured,
|
22
|
-
# @return [
|
21
|
+
# @note If no providers have been configured, +nil+ will be assigned.
|
22
|
+
# @return [TProvider, nil] the default provider to use when a provider
|
23
23
|
# cannot be resolved in {ProviderCollection#resolve #resolve}.
|
24
24
|
attr_reader :default
|
25
25
|
|
26
26
|
# Creates a new provider collection.
|
27
|
-
# @param [
|
28
|
-
# @param [Hash] providers the configured providers.
|
29
|
-
# @param [
|
27
|
+
# @param [Symbol] name the name for this provider collection.
|
28
|
+
# @param [Hash<Symbol, TProvider>] providers the configured providers.
|
29
|
+
# @param [TProvider, nil] default the configured default provider.
|
30
30
|
def initialize name, providers = {}, default = nil
|
31
31
|
@name = name
|
32
32
|
@configured_providers = providers
|
@@ -38,8 +38,9 @@ module Rambling
|
|
38
38
|
# Adds a new provider to the provider collection.
|
39
39
|
# @param [Symbol] extension the extension that the provider will
|
40
40
|
# correspond to.
|
41
|
-
# @param [
|
41
|
+
# @param [TProvider] provider the provider to add to the provider
|
42
42
|
# collection.
|
43
|
+
# @return [TProvider] the provider just added.
|
43
44
|
def add extension, provider
|
44
45
|
providers[extension] = provider
|
45
46
|
end
|
@@ -54,21 +55,22 @@ module Rambling
|
|
54
55
|
end
|
55
56
|
|
56
57
|
# List of configured providers.
|
57
|
-
# @return [Hash] the mapping of extensions to their
|
58
|
-
# providers.
|
58
|
+
# @return [Hash<Symbol, TProvider>] the mapping of extensions to their
|
59
|
+
# corresponding providers.
|
59
60
|
def providers
|
60
61
|
@providers ||= {}
|
61
62
|
end
|
62
63
|
|
63
64
|
# Resolves the provider from a filepath based on the file extension.
|
64
65
|
# @param [String] filepath the filepath to resolve into a provider.
|
65
|
-
# @return [
|
66
|
-
#
|
66
|
+
# @return [TProvider, nil] the provider for the given file's extension.
|
67
|
+
# {#default} if not found.
|
67
68
|
def resolve filepath
|
68
69
|
providers[file_format filepath] || default
|
69
70
|
end
|
70
71
|
|
71
72
|
# Resets the provider collection to the initial values.
|
73
|
+
# @return [void]
|
72
74
|
def reset
|
73
75
|
providers.clear
|
74
76
|
configured_providers.each { |k, v| self[k] = v }
|
@@ -77,7 +79,7 @@ module Rambling
|
|
77
79
|
|
78
80
|
# Get provider corresponding to a given format.
|
79
81
|
# @return [Array<Symbol>] the provider corresponding to that format.
|
80
|
-
# @see https://ruby-doc.org/core-2.
|
82
|
+
# @see https://ruby-doc.org/core-2.7.0/Hash.html#method-i-5B-5D
|
81
83
|
# Hash#keys
|
82
84
|
def formats
|
83
85
|
providers.keys
|
@@ -85,8 +87,8 @@ module Rambling
|
|
85
87
|
|
86
88
|
# Get provider corresponding to a given format.
|
87
89
|
# @param [Symbol] format the format to search for in the collection.
|
88
|
-
# @return [
|
89
|
-
# @see https://ruby-doc.org/core-2.
|
90
|
+
# @return [TProvider] the provider corresponding to that format.
|
91
|
+
# @see https://ruby-doc.org/core-2.7.0/Hash.html#method-i-5B-5D
|
90
92
|
# Hash#[]
|
91
93
|
def [] format
|
92
94
|
providers[format]
|
@@ -13,7 +13,7 @@ module Rambling
|
|
13
13
|
# Creates a new trie.
|
14
14
|
# @param [Nodes::Node] root the root node for the trie
|
15
15
|
# @param [Compressor] compressor responsible for compressing the trie
|
16
|
-
# @yield [
|
16
|
+
# @yield [self] the trie just initialized.
|
17
17
|
def initialize root, compressor
|
18
18
|
@root = root
|
19
19
|
@compressor = compressor
|
@@ -44,7 +44,7 @@ module Rambling
|
|
44
44
|
# Compresses the existing trie using redundant node elimination. Marks
|
45
45
|
# the trie as compressed. Does nothing if the trie has already been
|
46
46
|
# compressed.
|
47
|
-
# @return [
|
47
|
+
# @return [self]
|
48
48
|
# @note This method replaces the root {Nodes::Raw Raw} node with a
|
49
49
|
# {Nodes::Compressed Compressed} version of it.
|
50
50
|
def compress!
|
@@ -59,25 +59,24 @@ module Rambling
|
|
59
59
|
# compressed.
|
60
60
|
def compress
|
61
61
|
return self if root.compressed?
|
62
|
+
|
62
63
|
Rambling::Trie::Container.new compress_root, compressor
|
63
64
|
end
|
64
65
|
|
65
66
|
# Checks if a path for a word or partial word exists in the trie.
|
66
67
|
# @param [String] word the word or partial word to look for in the trie.
|
67
|
-
# @return [Boolean]
|
68
|
+
# @return [Boolean] +true+ if the word or partial word is found, +false+
|
68
69
|
# otherwise.
|
69
|
-
# @see Nodes::
|
70
|
-
# @see Nodes::Compressed#partial_word?
|
70
|
+
# @see Nodes::Node#partial_word?
|
71
71
|
def partial_word? word = ''
|
72
72
|
root.partial_word? word.chars
|
73
73
|
end
|
74
74
|
|
75
75
|
# Checks if a whole word exists in the trie.
|
76
76
|
# @param [String] word the word to look for in the trie.
|
77
|
-
# @return [Boolean]
|
78
|
-
# character corresponds to a terminal node,
|
79
|
-
# @see Nodes::
|
80
|
-
# @see Nodes::Compressed#word?
|
77
|
+
# @return [Boolean] +true+ only if the word is found and the last
|
78
|
+
# character corresponds to a terminal node, +false+ otherwise.
|
79
|
+
# @see Nodes::Node#word?
|
81
80
|
def word? word = ''
|
82
81
|
root.word? word.chars
|
83
82
|
end
|
@@ -86,8 +85,7 @@ module Rambling
|
|
86
85
|
# @param [String] word the word to look for in the trie.
|
87
86
|
# @return [Array<String>] all the words contained in the trie that start
|
88
87
|
# with the specified characters.
|
89
|
-
# @see Nodes::
|
90
|
-
# @see Nodes::Compressed#scan
|
88
|
+
# @see Nodes::Node#scan
|
91
89
|
def scan word = ''
|
92
90
|
root.scan(word.chars).to_a
|
93
91
|
end
|
@@ -98,15 +96,14 @@ module Rambling
|
|
98
96
|
# @return [Enumerator<String>] all the words in the given string that
|
99
97
|
# match a word in the trie.
|
100
98
|
# @yield [String] each word found in phrase.
|
101
|
-
# @see Nodes::Node#words_within
|
102
99
|
def words_within phrase
|
103
100
|
words_within_root(phrase).to_a
|
104
101
|
end
|
105
102
|
|
106
103
|
# Checks if there are any valid words in a given string.
|
107
104
|
# @param [String] phrase the string to look for matching words in.
|
108
|
-
# @return [Boolean]
|
109
|
-
# trie,
|
105
|
+
# @return [Boolean] +true+ if any word within phrase is contained in the
|
106
|
+
# trie, +false+ otherwise.
|
110
107
|
# @see Container#words_within
|
111
108
|
def words_within? phrase
|
112
109
|
words_within_root(phrase).any?
|
@@ -114,13 +111,14 @@ module Rambling
|
|
114
111
|
|
115
112
|
# Compares two trie data structures.
|
116
113
|
# @param [Container] other the trie to compare against.
|
117
|
-
# @return [Boolean]
|
114
|
+
# @return [Boolean] +true+ if the tries are equal, +false+ otherwise.
|
118
115
|
def == other
|
119
116
|
root == other.root
|
120
117
|
end
|
121
118
|
|
122
119
|
# Iterates over the words contained in the trie.
|
123
120
|
# @yield [String] the words contained in this trie node.
|
121
|
+
# @return [self]
|
124
122
|
def each
|
125
123
|
return enum_for :each unless block_given?
|
126
124
|
|
@@ -151,8 +149,8 @@ module Rambling
|
|
151
149
|
end
|
152
150
|
|
153
151
|
# Root node's children tree.
|
154
|
-
# @return [
|
155
|
-
# the root node
|
152
|
+
# @return [Hash<Symbol, Nodes::Node>] the children tree hash contained in
|
153
|
+
# the root node, consisting of +:letter => node+.
|
156
154
|
# @see Nodes::Node#children_tree
|
157
155
|
def children_tree
|
158
156
|
root.children_tree
|
@@ -160,15 +158,15 @@ module Rambling
|
|
160
158
|
|
161
159
|
# Indicates if the root {Nodes::Node Node} can be
|
162
160
|
# compressed or not.
|
163
|
-
# @return [Boolean]
|
164
|
-
# nodes with one child,
|
161
|
+
# @return [Boolean] +true+ for non-{Nodes::Node#terminal? terminal}
|
162
|
+
# nodes with one child, +false+ otherwise.
|
165
163
|
def compressed?
|
166
164
|
root.compressed?
|
167
165
|
end
|
168
166
|
|
169
167
|
# Array of words contained in the root {Nodes::Node Node}.
|
170
168
|
# @return [Array<String>] all words contained in this trie.
|
171
|
-
# @see https://ruby-doc.org/core-2.
|
169
|
+
# @see https://ruby-doc.org/core-2.7.0/Enumerable.html#method-i-to_a
|
172
170
|
# Enumerable#to_a
|
173
171
|
def to_a
|
174
172
|
root.to_a
|
@@ -7,12 +7,13 @@ module Rambling
|
|
7
7
|
include ::Enumerable
|
8
8
|
|
9
9
|
# Returns number of words contained in the trie
|
10
|
-
# @see https://ruby-doc.org/core-2.
|
10
|
+
# @see https://ruby-doc.org/core-2.7.0/Enumerable.html#method-i-count
|
11
11
|
# Enumerable#count
|
12
12
|
alias_method :size, :count
|
13
13
|
|
14
14
|
# Iterates over the words contained in the trie.
|
15
15
|
# @yield [String] the words contained in this trie node.
|
16
|
+
# @return [self]
|
16
17
|
def each
|
17
18
|
return enum_for :each unless block_given?
|
18
19
|
|
@@ -23,6 +24,8 @@ module Rambling
|
|
23
24
|
yield word
|
24
25
|
end
|
25
26
|
end
|
27
|
+
|
28
|
+
self
|
26
29
|
end
|
27
30
|
end
|
28
31
|
end
|
@@ -9,14 +9,14 @@ module Rambling
|
|
9
9
|
# trying to add a word to the current compressed trie node
|
10
10
|
# @param [String] _ the word to add to the trie.
|
11
11
|
# @raise [InvalidOperation] if the trie is already compressed.
|
12
|
-
# @return [
|
12
|
+
# @return [void]
|
13
13
|
def add _
|
14
14
|
raise Rambling::Trie::InvalidOperation,
|
15
15
|
'Cannot add word to compressed trie'
|
16
16
|
end
|
17
17
|
|
18
|
-
# Always return
|
19
|
-
# @return [Boolean] always
|
18
|
+
# Always return +true+ for a compressed node.
|
19
|
+
# @return [Boolean] always +true+ for a compressed node.
|
20
20
|
def compressed?
|
21
21
|
true
|
22
22
|
end
|
@@ -22,8 +22,8 @@ module Rambling
|
|
22
22
|
attr_reader :letter
|
23
23
|
|
24
24
|
# Child nodes tree.
|
25
|
-
# @return [Hash] the
|
26
|
-
# node
|
25
|
+
# @return [Hash<Symbol, Node>] the children tree hash, consisting of
|
26
|
+
# +:letter => node+.
|
27
27
|
attr_accessor :children_tree
|
28
28
|
|
29
29
|
# Parent node.
|
@@ -31,7 +31,7 @@ module Rambling
|
|
31
31
|
attr_accessor :parent
|
32
32
|
|
33
33
|
# Creates a new node.
|
34
|
-
# @param [Symbol, nil] letter the Node's letter value
|
34
|
+
# @param [Symbol, nil] letter the Node's letter value.
|
35
35
|
# @param [Node, nil] parent the parent of the current node.
|
36
36
|
def initialize letter = nil, parent = nil, children_tree = {}
|
37
37
|
@letter = letter
|
@@ -40,7 +40,7 @@ module Rambling
|
|
40
40
|
end
|
41
41
|
|
42
42
|
# Child nodes.
|
43
|
-
# @return [Array<Node>] the array of
|
43
|
+
# @return [Array<Node>] the array of child nodes contained
|
44
44
|
# in the current node.
|
45
45
|
def children
|
46
46
|
children_tree.values
|
@@ -51,20 +51,20 @@ module Rambling
|
|
51
51
|
def first_child
|
52
52
|
return if children_tree.empty?
|
53
53
|
|
54
|
-
|
55
|
-
|
56
|
-
|
54
|
+
# rubocop:disable Lint/UnreachableLoop
|
55
|
+
children_tree.each_value { |child| return child }
|
56
|
+
# rubocop:enable Lint/UnreachableLoop
|
57
57
|
end
|
58
58
|
|
59
59
|
# Indicates if the current node is the root node.
|
60
|
-
# @return [Boolean]
|
60
|
+
# @return [Boolean] +true+ if the node does not have a parent, +false+
|
61
61
|
# otherwise.
|
62
62
|
def root?
|
63
63
|
!parent
|
64
64
|
end
|
65
65
|
|
66
66
|
# Indicates if a {Node Node} is terminal or not.
|
67
|
-
# @return [Boolean]
|
67
|
+
# @return [Boolean] +true+ for terminal nodes, +false+ otherwise.
|
68
68
|
def terminal?
|
69
69
|
!!terminal
|
70
70
|
end
|
@@ -82,7 +82,7 @@ module Rambling
|
|
82
82
|
|
83
83
|
# Checks if a path for a set of characters exists in the trie.
|
84
84
|
# @param [Array<String>] chars the characters to look for in the trie.
|
85
|
-
# @return [Boolean]
|
85
|
+
# @return [Boolean] +true+ if the characters are found, +false+
|
86
86
|
# otherwise.
|
87
87
|
def partial_word? chars
|
88
88
|
return true if chars.empty?
|
@@ -92,8 +92,8 @@ module Rambling
|
|
92
92
|
|
93
93
|
# Checks if a path for set of characters represents a word in the trie.
|
94
94
|
# @param [Array<String>] chars the characters to look for in the trie.
|
95
|
-
# @return [Boolean]
|
96
|
-
#
|
95
|
+
# @return [Boolean] +true+ if the characters are found and form a word,
|
96
|
+
# +false+ otherwise.
|
97
97
|
def word? chars = []
|
98
98
|
return terminal? if chars.empty?
|
99
99
|
|
@@ -128,7 +128,7 @@ module Rambling
|
|
128
128
|
# Get {Node Node} corresponding to a given letter.
|
129
129
|
# @param [Symbol] letter the letter to search for in the node.
|
130
130
|
# @return [Node] the node corresponding to that letter.
|
131
|
-
# @see https://ruby-doc.org/core-2.
|
131
|
+
# @see https://ruby-doc.org/core-2.7.0/Hash.html#method-i-5B-5D
|
132
132
|
# Hash#[]
|
133
133
|
def [] letter
|
134
134
|
children_tree[letter]
|
@@ -139,7 +139,7 @@ module Rambling
|
|
139
139
|
# @param [Node] node the {Node Node} to assign to that letter.
|
140
140
|
# @return [Node] the node corresponding to the inserted or
|
141
141
|
# updated letter.
|
142
|
-
# @see https://ruby-doc.org/core-2.
|
142
|
+
# @see https://ruby-doc.org/core-2.7.0/Hash.html#method-i-5B-5D
|
143
143
|
# Hash#[]
|
144
144
|
def []= letter, node
|
145
145
|
children_tree[letter] = node
|
@@ -148,19 +148,19 @@ module Rambling
|
|
148
148
|
# Check if a {Node Node}'s children tree contains a given
|
149
149
|
# letter.
|
150
150
|
# @param [Symbol] letter the letter to search for in the node.
|
151
|
-
# @return [Boolean]
|
152
|
-
# @see https://ruby-doc.org/core-2.
|
151
|
+
# @return [Boolean] +true+ if the letter is present, +false+ otherwise.
|
152
|
+
# @see https://ruby-doc.org/core-2.7.0/Hash.html#method-i-has_key-3F
|
153
153
|
# Hash#key?
|
154
154
|
def key? letter
|
155
155
|
children_tree.key? letter
|
156
156
|
end
|
157
157
|
|
158
158
|
# Delete a given letter and its corresponding {Node Node} from
|
159
|
-
#
|
159
|
+
# this {Node Node}'s children tree.
|
160
160
|
# @param [Symbol] letter the letter to delete from the node's children
|
161
161
|
# tree.
|
162
162
|
# @return [Node] the node corresponding to the deleted letter.
|
163
|
-
# @see https://ruby-doc.org/core-2.
|
163
|
+
# @see https://ruby-doc.org/core-2.7.0/Hash.html#method-i-delete
|
164
164
|
# Hash#delete
|
165
165
|
def delete letter
|
166
166
|
children_tree.delete letter
|
@@ -17,8 +17,8 @@ module Rambling
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
# Always return
|
21
|
-
# @return [Boolean] always
|
20
|
+
# Always return +false+ for a raw (uncompressed) node.
|
21
|
+
# @return [Boolean] always +false+ for a raw (uncompressed) node.
|
22
22
|
def compressed?
|
23
23
|
false
|
24
24
|
end
|
@@ -3,14 +3,19 @@
|
|
3
3
|
module Rambling
|
4
4
|
module Trie
|
5
5
|
module Readers
|
6
|
-
# File reader for
|
7
|
-
class PlainText
|
8
|
-
# Yields each word read from a
|
6
|
+
# File reader for +.txt+ files.
|
7
|
+
class PlainText < Reader
|
8
|
+
# Yields each word read from a +.txt+ file.
|
9
9
|
# @param [String] filepath the full path of the file to load the words
|
10
10
|
# from.
|
11
11
|
# @yield [String] Each line read from the file.
|
12
|
+
# @return [self]
|
12
13
|
def each_word filepath
|
13
|
-
|
14
|
+
return enum_for :each_word unless block_given?
|
15
|
+
|
16
|
+
::File.foreach(filepath) { |line| yield line.chomp! }
|
17
|
+
|
18
|
+
self
|
14
19
|
end
|
15
20
|
end
|
16
21
|
end
|