victory 0.0.0 → 0.0.1
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/.gitignore +5 -0
- data/.rubocop.yml +11 -1
- data/README.md +4 -6
- data/Rakefile +11 -4
- data/USAGE.md +159 -0
- data/ext/algorithms/string/LICENSE.md +21 -0
- data/ext/algorithms/string/extconf.rb +4 -0
- data/ext/algorithms/string/string.c +68 -0
- data/ext/containers/bst/LICENSE.md +21 -0
- data/ext/containers/bst/bst.c +247 -0
- data/ext/containers/bst/extconf.rb +4 -0
- data/ext/containers/deque/LICENSE.md +21 -0
- data/ext/containers/deque/deque.c +247 -0
- data/ext/containers/deque/extconf.rb +4 -0
- data/ext/containers/rbtree_map/LICENSE.md +21 -0
- data/ext/containers/rbtree_map/extconf.rb +4 -0
- data/ext/containers/rbtree_map/rbtree.c +498 -0
- data/ext/containers/splaytree_map/LICENSE.md +21 -0
- data/ext/containers/splaytree_map/extconf.rb +4 -0
- data/ext/containers/splaytree_map/splaytree.c +419 -0
- data/ext/containers/xor_list/extconf.rb +4 -0
- data/ext/containers/xor_list/xor_list.c +122 -0
- data/lib/algorithms/search.rb +104 -0
- data/lib/algorithms/sort.rb +389 -0
- data/lib/algorithms/string.rb +29 -0
- data/lib/containers/deque.rb +193 -0
- data/lib/containers/heap.rb +524 -0
- data/lib/containers/kd_tree.rb +131 -0
- data/lib/containers/list.rb +81 -0
- data/lib/containers/prefix_tree.rb +61 -0
- data/lib/containers/priority_queue.rb +135 -0
- data/lib/containers/queue.rb +89 -0
- data/lib/containers/rb_tree_map.rb +420 -0
- data/lib/containers/splay_tree_map.rb +290 -0
- data/lib/containers/stack.rb +88 -0
- data/lib/containers/suffix_array.rb +92 -0
- data/lib/containers/trie.rb +204 -0
- data/lib/containers/tuple.rb +20 -0
- data/lib/victory/version.rb +1 -1
- data/lib/victory.rb +8 -1
- data/victory.gemspec +12 -3
- metadata +73 -12
- data/.idea/encodings.xml +0 -4
- data/.idea/misc.xml +0 -7
- data/.idea/modules.xml +0 -8
- data/.idea/victory.iml +0 -13
- data/.idea/workspace.xml +0 -233
- data/ext/victory/extconf.rb +0 -3
- data/ext/victory/victory.c +0 -9
- data/ext/victory/victory.h +0 -6
@@ -0,0 +1,81 @@
|
|
1
|
+
class List
|
2
|
+
Node = Struct.new(:data, :prev, :next)
|
3
|
+
def initialize
|
4
|
+
@first = nil
|
5
|
+
@last = nil
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.[](*arr)
|
9
|
+
from_a(arr)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.from_a(arr)
|
13
|
+
l = new
|
14
|
+
arr.each(&l.method(:push_front))
|
15
|
+
l
|
16
|
+
end
|
17
|
+
|
18
|
+
def empty?
|
19
|
+
@first == @last && @first.nil?
|
20
|
+
end
|
21
|
+
|
22
|
+
def push_front(element)
|
23
|
+
node = Node.new(element, nil, @first)
|
24
|
+
if @first.nil?
|
25
|
+
@last = node
|
26
|
+
else
|
27
|
+
@first.prev = node
|
28
|
+
end
|
29
|
+
@first = node
|
30
|
+
end
|
31
|
+
|
32
|
+
def pop_front
|
33
|
+
to_return = @first&.data
|
34
|
+
unless @first.nil?
|
35
|
+
@first = @first.next
|
36
|
+
if @first.nil?
|
37
|
+
@last = nil
|
38
|
+
else
|
39
|
+
@first.prev = nil unless @first.nil?
|
40
|
+
end
|
41
|
+
end
|
42
|
+
to_return
|
43
|
+
end
|
44
|
+
|
45
|
+
def push_back(element)
|
46
|
+
node = Node.new(element, @last, nil)
|
47
|
+
if @last.nil?
|
48
|
+
@first = node
|
49
|
+
else
|
50
|
+
@last.next = node
|
51
|
+
end
|
52
|
+
@last = node
|
53
|
+
end
|
54
|
+
|
55
|
+
def pop_back
|
56
|
+
to_return = @last&.data
|
57
|
+
unless @last.nil?
|
58
|
+
@last = @last.prev
|
59
|
+
if @last.nil?
|
60
|
+
@first = nil
|
61
|
+
else
|
62
|
+
@last.next = nil unless @last.nil?
|
63
|
+
end
|
64
|
+
end
|
65
|
+
to_return
|
66
|
+
end
|
67
|
+
|
68
|
+
def peek_front
|
69
|
+
@first&.data
|
70
|
+
end
|
71
|
+
|
72
|
+
def peek_back
|
73
|
+
@last&.data
|
74
|
+
end
|
75
|
+
|
76
|
+
alias push push_back
|
77
|
+
alias pop pop_back
|
78
|
+
alias unshift push_front
|
79
|
+
alias shift pop_front
|
80
|
+
end
|
81
|
+
L = List
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'containers/list'
|
2
|
+
|
3
|
+
class PrefixTree
|
4
|
+
class Node
|
5
|
+
attr_accessor :data, :children
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@data = nil
|
9
|
+
@children = {}
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@root = Node.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def <<(str, value = true)
|
18
|
+
insert(str, value)
|
19
|
+
end
|
20
|
+
|
21
|
+
def insert(str, value = true)
|
22
|
+
current = @root
|
23
|
+
str.each_char do |c|
|
24
|
+
current.children[c] = Node.new if current.children[c].nil?
|
25
|
+
current = current.children[c]
|
26
|
+
end
|
27
|
+
current.data = value
|
28
|
+
end
|
29
|
+
|
30
|
+
def [](str)
|
31
|
+
find(str)
|
32
|
+
end
|
33
|
+
|
34
|
+
def find(str)
|
35
|
+
current = @root
|
36
|
+
str.each_char do |c|
|
37
|
+
return nil if current.children[c].nil?
|
38
|
+
|
39
|
+
current = current.children[c]
|
40
|
+
end
|
41
|
+
current.data
|
42
|
+
end
|
43
|
+
|
44
|
+
def count_partial(str)
|
45
|
+
current = @root
|
46
|
+
str.each_char do |c|
|
47
|
+
return 0 if current.children[c].nil?
|
48
|
+
|
49
|
+
current = current.children[c]
|
50
|
+
end
|
51
|
+
stack = List.new
|
52
|
+
count = 0
|
53
|
+
current.children.each_value(&stack.method(:push))
|
54
|
+
until stack.empty?
|
55
|
+
current = stack.pop
|
56
|
+
count += 1 unless current.data.nil?
|
57
|
+
current.children.each_value(&stack.method(:push))
|
58
|
+
end
|
59
|
+
count
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'containers/heap'
|
2
|
+
|
3
|
+
# rdoc
|
4
|
+
# A Priority Queue is a data structure that behaves like a queue except that elements have an
|
5
|
+
# associated priority. The #next and #pop methods return the item with the next highest priority.
|
6
|
+
#
|
7
|
+
# Priority Queues are often used in graph problems, such as Dijkstra's Algorithm for shortest
|
8
|
+
# path, and the A* search algorithm for shortest path.
|
9
|
+
#
|
10
|
+
# This container is implemented using the Fibonacci heap included in the Collections library.
|
11
|
+
#
|
12
|
+
#
|
13
|
+
# MIT License
|
14
|
+
#
|
15
|
+
# Copyright (c) 2009 Kanwei Li
|
16
|
+
#
|
17
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
18
|
+
# of this software and associated documentation files (the "Software"), to deal
|
19
|
+
# in the Software without restriction, including without limitation the rights
|
20
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
21
|
+
# copies of the Software, and to permit persons to whom the Software is
|
22
|
+
# furnished to do so, subject to the following conditions:
|
23
|
+
#
|
24
|
+
# The above copyright notice and this permission notice shall be included in all
|
25
|
+
# copies or substantial portions of the Software.
|
26
|
+
#
|
27
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
28
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
29
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
30
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
31
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
32
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
33
|
+
# SOFTWARE.
|
34
|
+
class Containers::PriorityQueue
|
35
|
+
include Enumerable
|
36
|
+
|
37
|
+
# Create a new, empty PriorityQueue
|
38
|
+
def initialize(&block)
|
39
|
+
# We default to a priority queue that returns the largest value
|
40
|
+
block ||= lambda { |x, y| (x <=> y) == 1 }
|
41
|
+
@heap = Containers::Heap.new(&block)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns the number of elements in the queue.
|
45
|
+
#
|
46
|
+
# q = Containers::PriorityQueue.new
|
47
|
+
# q.size #=> 0
|
48
|
+
# q.push("Alaska", 1)
|
49
|
+
# q.size #=> 1
|
50
|
+
def size
|
51
|
+
@heap.size
|
52
|
+
end
|
53
|
+
alias_method :length, :size
|
54
|
+
|
55
|
+
# Add an object to the queue with associated priority.
|
56
|
+
#
|
57
|
+
# q = Containers::PriorityQueue.new
|
58
|
+
# q.push("Alaska", 1)
|
59
|
+
# q.pop #=> "Alaska"
|
60
|
+
def push(object, priority)
|
61
|
+
@heap.push(priority, object)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Clears all the items in the queue.
|
65
|
+
def clear
|
66
|
+
@heap.clear
|
67
|
+
end
|
68
|
+
|
69
|
+
# Returns true if the queue is empty, false otherwise.
|
70
|
+
def empty?
|
71
|
+
@heap.empty?
|
72
|
+
end
|
73
|
+
|
74
|
+
# call-seq:
|
75
|
+
# has_priority? priority -> boolean
|
76
|
+
#
|
77
|
+
# Return true if the priority is in the queue, false otherwise.
|
78
|
+
#
|
79
|
+
# q = PriorityQueue.new
|
80
|
+
# q.push("Alaska", 1)
|
81
|
+
#
|
82
|
+
# q.has_priority?(1) #=> true
|
83
|
+
# q.has_priority?(2) #=> false
|
84
|
+
def has_priority?(priority)
|
85
|
+
@heap.has_key?(priority)
|
86
|
+
end
|
87
|
+
|
88
|
+
# call-seq:
|
89
|
+
# next -> object
|
90
|
+
#
|
91
|
+
# Return the object with the next highest priority, but does not remove it
|
92
|
+
#
|
93
|
+
# q = Containers::PriorityQueue.new
|
94
|
+
# q.push("Alaska", 50)
|
95
|
+
# q.push("Delaware", 30)
|
96
|
+
# q.push("Georgia", 35)
|
97
|
+
# q.next #=> "Alaska"
|
98
|
+
def next
|
99
|
+
@heap.next
|
100
|
+
end
|
101
|
+
|
102
|
+
# call-seq:
|
103
|
+
# pop -> object
|
104
|
+
#
|
105
|
+
# Return the object with the next highest priority and removes it from the queue
|
106
|
+
#
|
107
|
+
# q = Containers::PriorityQueue.new
|
108
|
+
# q.push("Alaska", 50)
|
109
|
+
# q.push("Delaware", 30)
|
110
|
+
# q.push("Georgia", 35)
|
111
|
+
# q.pop #=> "Alaska"
|
112
|
+
# q.size #=> 2
|
113
|
+
def pop
|
114
|
+
@heap.pop
|
115
|
+
end
|
116
|
+
alias_method :next!, :pop
|
117
|
+
|
118
|
+
# call-seq:
|
119
|
+
# delete(priority) -> object
|
120
|
+
# delete(priority) -> nil
|
121
|
+
#
|
122
|
+
# Delete an object with specified priority from the queue. If there are duplicates, an
|
123
|
+
# arbitrary object with that priority is deleted and returned. Returns nil if there are
|
124
|
+
# no objects with the priority.
|
125
|
+
#
|
126
|
+
# q = PriorityQueue.new
|
127
|
+
# q.push("Alaska", 50)
|
128
|
+
# q.push("Delaware", 30)
|
129
|
+
# q.delete(50) #=> "Alaska"
|
130
|
+
# q.delete(10) #=> nil
|
131
|
+
def delete(priority)
|
132
|
+
@heap.delete(priority)
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'containers/deque'
|
2
|
+
|
3
|
+
# rdoc
|
4
|
+
# A Queue is a container that keeps elements in a first-in first-out (FIFO) order. Because of its
|
5
|
+
# properties, it is often used as a buffer.
|
6
|
+
#
|
7
|
+
# This implementation uses a doubly-linked list, guaranteeing O(1) complexity for all operations.
|
8
|
+
#
|
9
|
+
#
|
10
|
+
# MIT License
|
11
|
+
#
|
12
|
+
# Copyright (c) 2009 Kanwei Li
|
13
|
+
#
|
14
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
15
|
+
# of this software and associated documentation files (the "Software"), to deal
|
16
|
+
# in the Software without restriction, including without limitation the rights
|
17
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
18
|
+
# copies of the Software, and to permit persons to whom the Software is
|
19
|
+
# furnished to do so, subject to the following conditions:
|
20
|
+
#
|
21
|
+
# The above copyright notice and this permission notice shall be included in all
|
22
|
+
# copies or substantial portions of the Software.
|
23
|
+
#
|
24
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
25
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
26
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
27
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
28
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
29
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
30
|
+
# SOFTWARE.
|
31
|
+
class Containers::Queue
|
32
|
+
include Enumerable
|
33
|
+
# Create a new queue. Takes an optional array argument to initialize the queue.
|
34
|
+
#
|
35
|
+
# q = Containers::Queue.new([1, 2, 3])
|
36
|
+
# q.pop #=> 1
|
37
|
+
# q.pop #=> 2
|
38
|
+
def initialize(ary=[])
|
39
|
+
@container = Containers::Deque.new(ary)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns the next item from the queue but does not remove it.
|
43
|
+
#
|
44
|
+
# q = Containers::Queue.new([1, 2, 3])
|
45
|
+
# q.next #=> 1
|
46
|
+
# q.size #=> 3
|
47
|
+
def next
|
48
|
+
@container.front
|
49
|
+
end
|
50
|
+
|
51
|
+
# Adds an item to the queue.
|
52
|
+
#
|
53
|
+
# q = Containers::Queue.new([1])
|
54
|
+
# q.push(2)
|
55
|
+
# q.pop #=> 1
|
56
|
+
# q.pop #=> 2
|
57
|
+
def push(obj)
|
58
|
+
@container.push_back(obj)
|
59
|
+
end
|
60
|
+
alias_method :<<, :push
|
61
|
+
|
62
|
+
# Removes the next item from the queue and returns it.
|
63
|
+
#
|
64
|
+
# q = Containers::Queue.new([1, 2, 3])
|
65
|
+
# q.pop #=> 1
|
66
|
+
# q.size #=> 2
|
67
|
+
def pop
|
68
|
+
@container.pop_front
|
69
|
+
end
|
70
|
+
|
71
|
+
# Return the number of items in the queue.
|
72
|
+
#
|
73
|
+
# q = Containers::Queue.new([1, 2, 3])
|
74
|
+
# q.size #=> 3
|
75
|
+
def size
|
76
|
+
@container.size
|
77
|
+
end
|
78
|
+
|
79
|
+
# Returns true if the queue is empty, false otherwise.
|
80
|
+
def empty?
|
81
|
+
@container.empty?
|
82
|
+
end
|
83
|
+
|
84
|
+
# Iterate over the Queue in FIFO order.
|
85
|
+
def each(&block)
|
86
|
+
@container.each_forward(&block)
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|