ruby-anagrams 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 +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
|