victory 0.0.0 → 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|