ruby-anagrams 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 +4 -4
- data/lib/anagrams/anagrams.rb +50 -71
- data/lib/anagrams/enumerable.rb +3 -5
- data/lib/anagrams/root.rb +31 -10
- data/lib/anagrams/string_to_symbol_array.rb +9 -0
- data/lib/anagrams/subtrees.rb +23 -15
- data/lib/ruby-anagrams.rb +6 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ec31af73831e6d121c7a68d31d6f034d2ce8a056
|
4
|
+
data.tar.gz: 8199632ddb78960c4df770470f8228837967d305
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 71362f70f599bd5ed3ee10342614825ae306b0fea0f304952776c60d9787e2ebc890eb4642a25c3e92a1db8f94e17b418c195595b6c280a979f29118fbc114e2
|
7
|
+
data.tar.gz: 2f02a8847de091de0886aa97921742e83888476adefd1258788c633e5b3e0f6d82a9f22c7d8112ccdcfab5d25a1838a995918ac5794387192c78dc9d260d7cdf
|
data/lib/anagrams/anagrams.rb
CHANGED
@@ -7,85 +7,64 @@ module RubyAnagrams
|
|
7
7
|
# A Hash associating symbols with unique prime numbers.
|
8
8
|
SYM_PRIMES = (:a..:z).to_a.zip(Prime.first(26)).to_h
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
# root << "rise"
|
17
|
-
# root << "sire"
|
18
|
-
# root << "rie"
|
19
|
-
# #anagrams "rise" #=> ['rise', 'sire']
|
20
|
-
# @example with partial anagrams
|
21
|
-
# root << "rise"
|
22
|
-
# root << "sire"
|
23
|
-
# root << "rie"
|
24
|
-
# #anagrams "rise", include_partial: true #=> ['rie', 'rise', 'sire']
|
25
|
-
# @example with wildcards
|
26
|
-
# root << "bin"
|
27
|
-
# root << "ban"
|
28
|
-
# root << "bun"
|
29
|
-
# #anagrams "b*n" #=> ['ban', 'bin', 'bun']
|
30
|
-
# @param string [String] the string to find anagrams of.
|
31
|
-
# @param include_partial [Boolean] include partial anagrams?
|
32
|
-
# @return [Array<String>] all anagrams of the given string.
|
33
|
-
def anagrams string, include_partial: false
|
34
|
-
symbols = str_to_sym_a string
|
35
|
-
anagrams = []
|
36
|
-
find_symbol_permutations(symbols).each do |permutation|
|
37
|
-
anagrams.concat find_anagrams(as_product(permutation), include_partial: include_partial)
|
10
|
+
class << self
|
11
|
+
# Returns the product of each symbol's associated prime number.
|
12
|
+
# @param symbols [Array<Symbol>] the symbols to multiply.
|
13
|
+
# @return [Integer] the product of each symbol's associated prime number.
|
14
|
+
def sym_a_to_product symbols
|
15
|
+
symbols.inject(1) { |acc,sym| acc * SYM_PRIMES[sym] }
|
38
16
|
end
|
39
|
-
anagrams.uniq.sort
|
40
|
-
end
|
41
17
|
|
42
|
-
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
# @param include_partial [Boolean] include partial anagrams?
|
53
|
-
# @return [Array<String>] all anagrams whose product divides into the given
|
54
|
-
# product.
|
55
|
-
def find_anagrams product, include_partial: false
|
56
|
-
anagrams = []
|
57
|
-
anagrams << word if terminal? && (include_partial ? true : product == 1)
|
58
|
-
@children.each do |symbol,child|
|
59
|
-
if product % SYM_PRIMES[symbol] == 0
|
60
|
-
anagrams += child.find_anagrams(product / SYM_PRIMES[symbol], include_partial: include_partial)
|
61
|
-
end
|
18
|
+
# Returns all permutations of a symbol array, where "*" wildcards
|
19
|
+
# are replaced with symbols in the trie's alphabet.
|
20
|
+
# @param symbols [Array<Symbol>] the symbols to permute.
|
21
|
+
# @return [Array<Array<Symbol>>] the permutations.
|
22
|
+
def sym_a_permutations symbols
|
23
|
+
permutations = []
|
24
|
+
base_symbols = symbols.reject { |s| s == :* }
|
25
|
+
wildcard_permutations = (:a..:z).to_a.repeated_permutation(symbols.count :*)
|
26
|
+
wildcard_permutations.each do |permutation|
|
27
|
+
permutations << permutation.concat(base_symbols)
|
62
28
|
end
|
63
|
-
|
29
|
+
permutations.empty? ? [symbols] : permutations
|
64
30
|
end
|
31
|
+
end
|
65
32
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
symbol_permutations << non_wild_symbols + permutation
|
79
|
-
end
|
80
|
-
symbol_permutations.empty? ? [symbols] : symbol_permutations
|
33
|
+
# Returns all string anagrams of the given symbol array by calling
|
34
|
+
# #anagrams_by_product on all permutations of the symbol array.
|
35
|
+
# @note Default behavior only includes complete anagrams. Partial anagrams
|
36
|
+
# can be included by setting partial to true.
|
37
|
+
# @param symbols [Array<Symbol>] the symbols to find anagrams for.
|
38
|
+
# @param partial [Boolean] include partial anagrams?
|
39
|
+
# @return [Array<Array<String>>] all anagrams of the symbols.
|
40
|
+
def search_for_anagrams symbols, partial: partial
|
41
|
+
anagrams = []
|
42
|
+
Anagrams.sym_a_permutations(symbols).each do |permutation|
|
43
|
+
product = Anagrams.sym_a_to_product permutation
|
44
|
+
anagrams.concat anagrams_by_product(product, partial: partial)
|
81
45
|
end
|
46
|
+
anagrams.uniq.sort
|
47
|
+
end
|
82
48
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
49
|
+
# Depth-first searches the trie data structure for anagrams based on their
|
50
|
+
# node's associated prime number. Returns an array of anagrams whose product
|
51
|
+
# divides into the given product.
|
52
|
+
# @note Default behavior only includes words with a product equal to the
|
53
|
+
# given product. Words that are divisors of the given product can be
|
54
|
+
# included by setting partial to true.
|
55
|
+
# @param product [Integer] a product of a symbol array.
|
56
|
+
# @param partial [Boolean] include partial anagrams?
|
57
|
+
# @return [Array<String>] all anagrams of the given product.
|
58
|
+
def anagrams_by_product product, partial: partial
|
59
|
+
anagrams = []
|
60
|
+
anagrams << word if terminal? && (partial ? true : product == 1)
|
61
|
+
@children.each do |symbol,child|
|
62
|
+
if product % SYM_PRIMES[symbol] == 0
|
63
|
+
anagrams += child.anagrams_by_product(product / SYM_PRIMES[symbol], partial: partial)
|
64
|
+
end
|
88
65
|
end
|
66
|
+
anagrams
|
67
|
+
end
|
89
68
|
|
90
69
|
end
|
91
70
|
end
|
data/lib/anagrams/enumerable.rb
CHANGED
@@ -9,11 +9,9 @@ module RubyAnagrams
|
|
9
9
|
# an Enumerator is returned.
|
10
10
|
# @return [Enumerator] the enumerator for the words in the trie data structure.
|
11
11
|
def each &block
|
12
|
-
enumerator = Enumerator.new do |
|
13
|
-
|
14
|
-
@children.each_value
|
15
|
-
child.each { |word| y << word }
|
16
|
-
end
|
12
|
+
enumerator = Enumerator.new do |yielder|
|
13
|
+
yielder << word if terminal?
|
14
|
+
@children.each_value { |child| child.each { |word| yielder << word } }
|
17
15
|
end
|
18
16
|
block.nil? ? enumerator : enumerator.each(&block)
|
19
17
|
end
|
data/lib/anagrams/root.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
# Namespace for the Ruby-Anagrams gem.
|
2
1
|
module RubyAnagrams
|
3
2
|
# A representation of the Root node of the trie data structure.
|
4
3
|
# @author Connor Lay
|
5
4
|
class Root < Node
|
5
|
+
|
6
6
|
# Creates a new trie.
|
7
7
|
# @param path [String, nil] the path to a dictionary text file.
|
8
8
|
# @return [Root] the Root node of the trie just created.
|
@@ -19,25 +19,46 @@ module RubyAnagrams
|
|
19
19
|
# @param word [String] the new word to add to the trie.
|
20
20
|
# @return [String] the word just added to the trie.
|
21
21
|
def << word
|
22
|
-
symbols =
|
22
|
+
symbols = word.to_sym_a
|
23
23
|
add_to_subtree symbols
|
24
24
|
end
|
25
25
|
|
26
|
+
alias :add :<<
|
27
|
+
|
26
28
|
# If the trie contains the word.
|
27
29
|
# @param word [String] the word to search for.
|
28
30
|
# @return [Boolean] true if the word is found, false otherwise.
|
29
31
|
def include? word
|
30
|
-
symbols =
|
32
|
+
symbols = word.to_sym_a
|
31
33
|
search_subtree symbols
|
32
34
|
end
|
33
35
|
|
34
|
-
|
35
|
-
|
36
|
-
#
|
37
|
-
# @
|
38
|
-
#
|
39
|
-
|
40
|
-
|
36
|
+
alias :contains? :include?
|
37
|
+
|
38
|
+
# Returns all anagrams of the given word. Wildcards are indicated with "*".
|
39
|
+
# @note Default behavior only includes complete anagrams. Partial anagrams
|
40
|
+
# can be included by setting partial to true.
|
41
|
+
# @example without partial anagrams
|
42
|
+
# root << "rise"
|
43
|
+
# root << "sire"
|
44
|
+
# root << "rie"
|
45
|
+
# #anagrams "rise" #=> ['rise', 'sire']
|
46
|
+
# @example with partial anagrams
|
47
|
+
# root << "rise"
|
48
|
+
# root << "sire"
|
49
|
+
# root << "rie"
|
50
|
+
# #anagrams "rise", partial: true #=> ['rie', 'rise', 'sire']
|
51
|
+
# @example with wildcards
|
52
|
+
# root << "bin"
|
53
|
+
# root << "ban"
|
54
|
+
# root << "bun"
|
55
|
+
# #anagrams "b*n" #=> ['ban', 'bin', 'bun']
|
56
|
+
# @param word [String] the word to find anagrams for.
|
57
|
+
# @param partial [Boolean] include partial anagrams?
|
58
|
+
# @return [Array<String>] anagrams of word.
|
59
|
+
def anagrams word, partial: false
|
60
|
+
symbols = word.to_sym_a
|
61
|
+
search_for_anagrams symbols, partial: partial
|
41
62
|
end
|
42
63
|
|
43
64
|
end
|
data/lib/anagrams/subtrees.rb
CHANGED
@@ -14,33 +14,41 @@ module RubyAnagrams
|
|
14
14
|
nodes
|
15
15
|
end
|
16
16
|
|
17
|
+
# Descends the trie data structure following the given sequence of symbols.
|
18
|
+
# The last node visited is returned, either because it is a leaf or there
|
19
|
+
# are no symbols left.
|
20
|
+
# @note This method alters the symbol array.
|
21
|
+
# @param symbols [Array<Symbol>] the symbol sequence to follow.
|
22
|
+
# @return [Node] the last node visited.
|
23
|
+
def descend symbols
|
24
|
+
return self unless symbol = symbols[0]
|
25
|
+
return self unless child = @children[symbol]
|
26
|
+
symbols.slice! 0
|
27
|
+
child.descend symbols
|
28
|
+
end
|
29
|
+
|
17
30
|
protected
|
18
31
|
# Descends the trie data structure, adding nodes when needed, for a given
|
19
32
|
# sequence of symbols. The last node visited is designated as a terminal.
|
20
33
|
# @param symbols [Array<Symbol>] the symbol sequence to follow.
|
21
34
|
# @return [String] the word represented by the last node visited.
|
22
35
|
def add_to_subtree symbols
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
s = symbols.slice! 0
|
28
|
-
unless child = @children[s]
|
29
|
-
child = Node.new s, self
|
30
|
-
@children[s] = child
|
36
|
+
current = descend symbols
|
37
|
+
symbols.each do |symbol|
|
38
|
+
current[symbol] = Node.new symbol, current
|
39
|
+
current = current[symbol]
|
31
40
|
end
|
32
|
-
|
41
|
+
current.terminal!
|
42
|
+
current.word
|
33
43
|
end
|
34
44
|
|
35
|
-
#
|
36
|
-
#
|
45
|
+
# Depth-first searches the trie data structure for a node representing a
|
46
|
+
# given sequence of symbols.
|
37
47
|
# @param symbols [Array<Symbol>] the symbol sequence to follow.
|
38
48
|
# @return [Boolean] true if the last node visited is a terminal, false otherwise.
|
39
49
|
def search_subtree symbols
|
40
|
-
|
41
|
-
|
42
|
-
return false unless child = @children[s]
|
43
|
-
child.search_subtree symbols
|
50
|
+
current = descend symbols
|
51
|
+
current.terminal? && symbols.empty?
|
44
52
|
end
|
45
53
|
|
46
54
|
end
|
data/lib/ruby-anagrams.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
|
+
require_relative 'anagrams/string_to_symbol_array'
|
1
2
|
require_relative 'anagrams/subtrees'
|
2
3
|
require_relative 'anagrams/enumerable'
|
3
4
|
require_relative 'anagrams/anagrams'
|
4
5
|
require_relative 'anagrams/node'
|
5
|
-
require_relative 'anagrams/root'
|
6
|
+
require_relative 'anagrams/root'
|
7
|
+
|
8
|
+
module RubyAnagrams
|
9
|
+
# Namespace for the Ruby-Anagrams gem.
|
10
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-anagrams
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Connor Lay
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -76,6 +76,7 @@ files:
|
|
76
76
|
- lib/anagrams/enumerable.rb
|
77
77
|
- lib/anagrams/node.rb
|
78
78
|
- lib/anagrams/root.rb
|
79
|
+
- lib/anagrams/string_to_symbol_array.rb
|
79
80
|
- lib/anagrams/subtrees.rb
|
80
81
|
- lib/ruby-anagrams.rb
|
81
82
|
homepage: https://github.com/connorlay/ruby-anagrams
|