ds 0.0.4 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rubocop.yml +11 -0
- data/.rubocop_todo.yml +452 -0
- data/.travis.yml +12 -0
- data/Gemfile +1 -1
- data/README.rdoc +185 -214
- data/Rakefile +8 -3
- data/ds.gemspec +16 -13
- data/lib/ds.rb +20 -30
- data/lib/ds/{matrixes → arrays}/array_2d.rb +9 -10
- data/lib/ds/arrays/expandable_array.rb +34 -0
- data/lib/ds/arrays/heap_store.rb +32 -0
- data/lib/ds/arrays/tri_matrix.rb +33 -0
- data/lib/ds/lists/list.rb +310 -186
- data/lib/ds/lists/list_element.rb +14 -11
- data/lib/ds/pair.rb +4 -4
- data/lib/ds/queues/priority_queue.rb +33 -20
- data/lib/ds/queues/simple_queue.rb +55 -0
- data/lib/ds/sets/indexed_set.rb +37 -0
- data/lib/ds/stacks/stack.rb +25 -17
- data/lib/ds/trees/binary_heap.rb +71 -66
- data/lib/ds/trees/binary_tree.rb +40 -44
- data/lib/ds/trees/red_black_tree.rb +123 -0
- data/lib/ds/trees/red_black_tree/node.rb +21 -0
- data/lib/ds/trees/tree.rb +50 -48
- data/lib/ds/trees/tree_walker.rb +73 -144
- data/lib/ds/trees/trie.rb +67 -37
- data/lib/ds/trees/trie/node.rb +48 -0
- data/lib/ds/version.rb +2 -1
- data/test/help.rb +3 -6
- data/test/performance/binary_heap_performance_test.rb +20 -0
- data/test/performance/list_performance_test.rb +36 -0
- data/test/performance/priority_queue_performance.rb +32 -0
- data/test/performance/rbt_performance_test.rb +17 -0
- data/test/performance/simple_queue_performance_test.rb +37 -0
- data/test/performance/stack_test.rb +45 -0
- data/test/test_array2d.rb +29 -31
- data/test/test_binary_heap.rb +29 -23
- data/test/test_binary_tree.rb +30 -20
- data/test/test_expandable_array.rb +6 -10
- data/test/test_heap_store.rb +34 -0
- data/test/test_indexed_set.rb +26 -0
- data/test/test_list.rb +226 -109
- data/test/test_list_element.rb +34 -16
- data/test/test_pair.rb +5 -8
- data/test/test_priority_queue.rb +43 -64
- data/test/test_queue.rb +12 -61
- data/test/test_red_black_tree.rb +46 -0
- data/test/test_stack.rb +35 -39
- data/test/test_tree.rb +42 -29
- data/test/test_tree_walker.rb +27 -52
- data/test/test_tri_matrix.rb +6 -11
- data/test/test_trie.rb +59 -17
- metadata +80 -35
- data/lib/ds/ext/array_x.rb +0 -35
- data/lib/ds/graphs/digraph.rb +0 -20
- data/lib/ds/graphs/edge.rb +0 -15
- data/lib/ds/graphs/graph.rb +0 -111
- data/lib/ds/graphs/graph_as_matrix.rb +0 -113
- data/lib/ds/graphs/graph_as_tri_matrix.rb +0 -24
- data/lib/ds/lists/cyclic_list.rb +0 -21
- data/lib/ds/lists/ring.rb +0 -42
- data/lib/ds/matrixes/expandable_array.rb +0 -37
- data/lib/ds/matrixes/tri_matrix.rb +0 -30
- data/lib/ds/queues/queue.rb +0 -53
- data/lib/ds/sets/ordered_set.rb +0 -32
- data/lib/ds/trees/binary_search_tree.rb +0 -34
- data/lib/ds/trees/complete_binary_tree.rb +0 -60
- data/test/test_array_x.rb +0 -51
- data/test/test_binary_search_tree.rb +0 -39
- data/test/test_complete_binary_tree.rb +0 -58
- data/test/test_digraph.rb +0 -134
- data/test/test_graph.rb +0 -80
- data/test/test_ordered_set.rb +0 -28
- data/test/test_ring.rb +0 -28
data/test/test_list_element.rb
CHANGED
@@ -1,56 +1,74 @@
|
|
1
1
|
require 'help'
|
2
2
|
|
3
|
-
describe
|
4
|
-
|
3
|
+
describe 'List Element' do
|
5
4
|
before do
|
6
5
|
@empty_el = ListElement.new
|
7
6
|
@el = ListElement.new(1)
|
8
7
|
end
|
9
8
|
|
10
|
-
describe
|
11
|
-
|
9
|
+
describe 'not initialized' do
|
12
10
|
before do
|
13
11
|
@empty_el = ListElement.new
|
14
12
|
end
|
15
13
|
|
16
|
-
it
|
14
|
+
it 'should have no elements.' do
|
17
15
|
@empty_el.data.must_be_nil
|
18
16
|
end
|
19
17
|
|
20
|
-
it
|
18
|
+
it 'should be tail.' do
|
21
19
|
assert @empty_el.tail?
|
22
20
|
end
|
23
21
|
|
24
|
-
it
|
25
|
-
@empty_el.
|
22
|
+
it 'should be head.' do
|
23
|
+
assert @empty_el.head?
|
24
|
+
end
|
25
|
+
|
26
|
+
it '#append should return appended element.' do
|
27
|
+
el = @empty_el.append(2)
|
28
|
+
el.must_be_instance_of ListElement
|
29
|
+
el.data.must_equal 2
|
30
|
+
el.must_equal @empty_el.next
|
31
|
+
end
|
32
|
+
|
33
|
+
it '#append should link element with another.' do
|
34
|
+
@next = @empty_el.append(2)
|
35
|
+
@next.must_be_instance_of ListElement
|
26
36
|
@empty_el.next.wont_be_nil
|
27
37
|
@empty_el.next.must_be_instance_of ListElement
|
28
38
|
@empty_el.next.data.must_equal 2
|
39
|
+
@next.prev.wont_be_nil
|
40
|
+
@next.prev.must_be_instance_of ListElement
|
29
41
|
end
|
30
42
|
end
|
31
43
|
|
32
|
-
|
33
|
-
describe "initialized" do
|
34
|
-
|
44
|
+
describe 'initialized' do
|
35
45
|
before do
|
36
46
|
@el = ListElement.new(1)
|
37
47
|
end
|
38
48
|
|
39
|
-
it
|
49
|
+
it 'should have one element' do
|
40
50
|
@el.data.must_equal 1
|
41
51
|
end
|
42
52
|
|
43
|
-
it
|
53
|
+
it 'should be tail.' do
|
44
54
|
assert @el.tail?
|
45
55
|
end
|
46
56
|
|
47
|
-
it
|
57
|
+
it 'should be head.' do
|
58
|
+
assert @el.head?
|
59
|
+
end
|
60
|
+
|
61
|
+
it '#append should link element with another.' do
|
62
|
+
@next = @el.append(2)
|
63
|
+
@next.must_be_instance_of ListElement
|
48
64
|
@el.append(2).must_be_instance_of ListElement
|
49
65
|
@el.next.wont_be_nil
|
50
66
|
@el.next.must_be_instance_of ListElement
|
51
67
|
@el.next.data.must_equal 2
|
52
|
-
end
|
53
68
|
|
69
|
+
@next.prev.wont_be_nil
|
70
|
+
@next.prev.must_be_instance_of ListElement
|
71
|
+
@next.prev.data.must_equal 1
|
72
|
+
end
|
54
73
|
end
|
55
|
-
|
56
74
|
end
|
data/test/test_pair.rb
CHANGED
@@ -1,26 +1,23 @@
|
|
1
1
|
require 'help'
|
2
2
|
|
3
3
|
describe Pair do
|
4
|
-
|
5
4
|
before do
|
6
|
-
@pair = Pair.new(1,2)
|
5
|
+
@pair = Pair.new(1, 2)
|
7
6
|
end
|
8
7
|
|
9
|
-
it
|
8
|
+
it '#first should return first element of a pair' do
|
10
9
|
@pair.first.must_equal 1
|
11
10
|
end
|
12
11
|
|
13
|
-
it
|
12
|
+
it '#key should return first element of a pair' do
|
14
13
|
@pair.key.must_equal 1
|
15
14
|
end
|
16
15
|
|
17
|
-
it
|
16
|
+
it '#second should return second element of a pair' do
|
18
17
|
@pair.second.must_equal 2
|
19
18
|
end
|
20
19
|
|
21
|
-
it
|
20
|
+
it '#value should return second element of a pair' do
|
22
21
|
@pair.value.must_equal 2
|
23
22
|
end
|
24
|
-
|
25
23
|
end
|
26
|
-
|
data/test/test_priority_queue.rb
CHANGED
@@ -1,49 +1,43 @@
|
|
1
1
|
require 'help'
|
2
2
|
|
3
3
|
describe PriorityQueue do
|
4
|
-
|
5
|
-
describe "Empty Priority Queue" do
|
6
|
-
|
4
|
+
describe 'Empty priority queue' do
|
7
5
|
before do
|
8
6
|
@empty_queue = PriorityQueue.new
|
9
7
|
end
|
10
8
|
|
11
|
-
it
|
9
|
+
it 'should be empty.' do
|
12
10
|
assert @empty_queue.empty?
|
13
11
|
end
|
14
12
|
|
15
|
-
it
|
13
|
+
it 'should have zero elements.' do
|
16
14
|
@empty_queue.length.must_equal 0
|
17
15
|
end
|
18
16
|
end
|
19
17
|
|
20
|
-
|
21
|
-
describe "Not empty priority queue" do
|
22
|
-
|
18
|
+
describe 'Not empty priority queue' do
|
23
19
|
before do
|
24
20
|
@queue = PriorityQueue.new
|
25
21
|
@queue.enqueue :important, 2
|
26
22
|
@queue.enqueue :not_important, 1
|
27
23
|
end
|
28
24
|
|
29
|
-
it
|
25
|
+
it 'should not be empty.' do
|
30
26
|
refute @queue.empty?
|
31
27
|
@queue.length.must_equal 2
|
32
|
-
|
33
28
|
end
|
34
29
|
|
35
|
-
it
|
30
|
+
it '#peek should return element with highest priority.' do
|
36
31
|
@queue.peek.must_equal :important
|
37
32
|
end
|
38
33
|
|
39
|
-
|
40
|
-
it "#enqueue and #push should add element to priority queue." do
|
34
|
+
it '#enqueue and #push should add element to priority queue.' do
|
41
35
|
@queue.enqueue :very_important, 5
|
42
36
|
@queue.push :nevermind, 0
|
43
37
|
@queue.length.must_equal 4
|
44
38
|
end
|
45
39
|
|
46
|
-
it
|
40
|
+
it '#dequeue and #shift should remove element with highest priority.' do
|
47
41
|
x = @queue.dequeue
|
48
42
|
@queue.length.must_equal 1
|
49
43
|
x.must_equal :important
|
@@ -53,37 +47,61 @@ describe PriorityQueue do
|
|
53
47
|
end
|
54
48
|
end
|
55
49
|
|
56
|
-
describe
|
50
|
+
describe 'Not empty priority queue with custom order' do
|
51
|
+
before do
|
52
|
+
@queue = PriorityQueue.new { |a, b| a < b }
|
53
|
+
@queue.enqueue 'gamma', 'g'
|
54
|
+
@queue.enqueue 'alpha', 'a'
|
55
|
+
@queue.enqueue 'beta', 'b'
|
56
|
+
end
|
57
57
|
|
58
|
+
it 'should not be empty.' do
|
59
|
+
refute @queue.empty?
|
60
|
+
@queue.length.must_equal 3
|
61
|
+
end
|
62
|
+
|
63
|
+
it '#peek should return element with highest priority.' do
|
64
|
+
@queue.peek.must_equal 'alpha'
|
65
|
+
end
|
66
|
+
|
67
|
+
it '#dequeue and #shift should remove element with highest priority.' do
|
68
|
+
x = @queue.dequeue
|
69
|
+
@queue.length.must_equal 2
|
70
|
+
x.must_equal 'alpha'
|
71
|
+
@queue.dequeue.must_equal 'beta'
|
72
|
+
@queue.length.must_equal 1
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe 'PriorityQueue with duplications' do
|
58
77
|
before do
|
59
|
-
@dup_queue = PriorityQueue.new
|
60
|
-
@dup_queue.enqueue :same_important, 2
|
78
|
+
@dup_queue = PriorityQueue.new(Pair.new(2, :same_important))
|
61
79
|
@dup_queue.enqueue :important, 2
|
62
80
|
@dup_queue.enqueue :not_important, 1
|
63
81
|
end
|
64
82
|
|
65
|
-
it
|
83
|
+
it 'should not be empty' do
|
66
84
|
refute @dup_queue.empty?
|
67
85
|
@dup_queue.length.must_equal 3
|
68
86
|
end
|
69
87
|
|
70
|
-
it
|
71
|
-
assert [:important
|
88
|
+
it '#peek should return element with highest priority.' do
|
89
|
+
assert [:important, :same_important].include? @dup_queue.peek
|
72
90
|
@dup_queue.dequeue
|
73
|
-
assert [:important
|
91
|
+
assert [:important, :same_important].include? @dup_queue.peek
|
74
92
|
@dup_queue.dequeue
|
75
93
|
@dup_queue.peek.must_equal :not_important
|
76
94
|
end
|
77
95
|
|
78
|
-
it
|
96
|
+
it '#enqueue and #push should add element to priority queue.' do
|
79
97
|
@dup_queue.push :nevermind, 0
|
80
98
|
@dup_queue.push :another_important, 2
|
81
99
|
@dup_queue.length.must_equal 5
|
82
100
|
end
|
83
101
|
|
84
|
-
it
|
85
|
-
x
|
86
|
-
assert [:important
|
102
|
+
it '#dequeue and #shift should remove element with highest priority.' do
|
103
|
+
x = @dup_queue.dequeue
|
104
|
+
assert [:important, :same_important].include? x
|
87
105
|
@dup_queue.length.must_equal 2
|
88
106
|
|
89
107
|
@dup_queue.enqueue :important, 2
|
@@ -92,43 +110,4 @@ describe PriorityQueue do
|
|
92
110
|
@dup_queue.dequeue.must_equal :important
|
93
111
|
end
|
94
112
|
end
|
95
|
-
|
96
|
-
|
97
|
-
if ENV['BENCH']
|
98
|
-
describe "performance" do
|
99
|
-
|
100
|
-
before do
|
101
|
-
|
102
|
-
@queue = PriorityQueue.new
|
103
|
-
10000.times do |n|
|
104
|
-
@queue.push :elem, rand(10)
|
105
|
-
end
|
106
|
-
|
107
|
-
@empty_queue = PriorityQueue.new
|
108
|
-
end
|
109
|
-
|
110
|
-
|
111
|
-
bench_performance_constant "#accessing max element should be const operation.", 0.999 do |n|
|
112
|
-
n.times do
|
113
|
-
@queue.peek
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
|
118
|
-
bench_performance_constant "#removing max element should be log operation.", 0.999 do |n|
|
119
|
-
n.times do
|
120
|
-
@queue.dequeue
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
bench_performance_constant "creating new priority queue should be linear operation.", 0.999 do |n|
|
125
|
-
n.times do
|
126
|
-
@empty_queue.push :elem, rand(10)
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
end
|
133
|
-
end
|
134
113
|
end
|
data/test/test_queue.rb
CHANGED
@@ -1,36 +1,27 @@
|
|
1
1
|
require 'help'
|
2
2
|
|
3
|
-
describe
|
4
|
-
|
5
|
-
describe "Empty Queue" do
|
6
|
-
|
3
|
+
describe SimpleQueue do
|
4
|
+
describe 'empty queue' do
|
7
5
|
before do
|
8
|
-
@empty_queue =
|
6
|
+
@empty_queue = SimpleQueue.new
|
9
7
|
end
|
10
8
|
|
11
|
-
it
|
9
|
+
it 'should be empty.' do
|
12
10
|
assert @empty_queue.empty?
|
13
11
|
end
|
14
12
|
|
15
|
-
it
|
13
|
+
it 'should have zero elements.' do
|
16
14
|
@empty_queue.length.must_equal 0
|
17
15
|
end
|
18
16
|
end
|
19
17
|
|
20
|
-
|
21
|
-
describe "Not empty queue" do
|
22
|
-
|
18
|
+
describe 'not empty queue' do
|
23
19
|
before do
|
24
|
-
@queue =
|
25
|
-
@
|
26
|
-
@queue.enqueue 2
|
27
|
-
|
28
|
-
@queue2 = DS::Queue.create
|
29
|
-
@queue2.enqueue 1
|
30
|
-
@queue2.enqueue 2
|
20
|
+
@queue = SimpleQueue.new(1, 2)
|
21
|
+
@queue2 = SimpleQueue.create(1, 2)
|
31
22
|
end
|
32
23
|
|
33
|
-
it
|
24
|
+
it 'should not be empty.' do
|
34
25
|
refute @queue.empty?
|
35
26
|
@queue.length.must_equal 2
|
36
27
|
|
@@ -38,13 +29,12 @@ describe Queue do
|
|
38
29
|
@queue2.length.must_equal 2
|
39
30
|
end
|
40
31
|
|
41
|
-
it
|
32
|
+
it '#peek should return element from forehead of queue.' do
|
42
33
|
@queue.peek.must_equal 1
|
43
34
|
@queue2.peek.must_equal 1
|
44
35
|
end
|
45
36
|
|
46
|
-
|
47
|
-
it "#enqueue and #push should add element to queue." do
|
37
|
+
it '#enqueue and #push should add element to queue.' do
|
48
38
|
@queue.enqueue 3
|
49
39
|
@queue.length.must_equal 3
|
50
40
|
|
@@ -58,7 +48,7 @@ describe Queue do
|
|
58
48
|
@queue2.length.must_equal 4
|
59
49
|
end
|
60
50
|
|
61
|
-
it
|
51
|
+
it '#dequeue and #shift should remove element from queue.' do
|
62
52
|
x = @queue.dequeue
|
63
53
|
@queue.length.must_equal 1
|
64
54
|
x.must_equal 1
|
@@ -67,44 +57,5 @@ describe Queue do
|
|
67
57
|
@queue2.length.must_equal 1
|
68
58
|
x.must_equal 1
|
69
59
|
end
|
70
|
-
|
71
|
-
|
72
|
-
if ENV['BENCH']
|
73
|
-
describe "performance" do
|
74
|
-
|
75
|
-
before do
|
76
|
-
100000.times do |n|
|
77
|
-
@queue.push 4
|
78
|
-
@queue2.push 4
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
|
83
|
-
bench_performance_constant "#shift(array implementation) should be const operation.", 0.999 do |n|
|
84
|
-
n.times do
|
85
|
-
@queue.shift
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
bench_performance_constant "#shift(list implementation) should be const operation.", 0.999 do |n|
|
90
|
-
n.times do
|
91
|
-
@queue2.shift
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
bench_performance_constant "#push(array implementation) should be const operation.", 0.999 do |n|
|
96
|
-
n.times do
|
97
|
-
@queue.push 2
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
bench_performance_constant "#push(list implementation) should be const operation.", 0.999 do |n|
|
102
|
-
n.times do
|
103
|
-
@queue2.push 2
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
60
|
end
|
110
61
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'help'
|
2
|
+
|
3
|
+
describe Tree do
|
4
|
+
before do
|
5
|
+
@tree = RedBlackTree.new
|
6
|
+
@tree.insert(:a, 1)
|
7
|
+
@tree.insert(:b, 2)
|
8
|
+
end
|
9
|
+
|
10
|
+
it '#new creates new RBT from hash' do
|
11
|
+
@dict = RedBlackTree.new(a: 1, b: 2, c: 3)
|
12
|
+
@dict[:a].must_equal 1
|
13
|
+
@dict[:b].must_equal 2
|
14
|
+
@dict[:c].must_equal 3
|
15
|
+
end
|
16
|
+
|
17
|
+
it '#insert add new element into tree' do
|
18
|
+
@tree.insert(:c, 3)
|
19
|
+
@tree.get(:c).must_equal 3
|
20
|
+
end
|
21
|
+
|
22
|
+
it '#get returns element if it is on tree' do
|
23
|
+
@tree.get(:b).must_equal 2
|
24
|
+
@tree.get(:x).must_equal nil
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'has hash like methods' do
|
28
|
+
@tree[:c] = 3
|
29
|
+
@tree[:c].must_equal 3
|
30
|
+
end
|
31
|
+
|
32
|
+
it '#size returns tree size' do
|
33
|
+
@tree.size.must_equal(2)
|
34
|
+
end
|
35
|
+
|
36
|
+
it '#map returns nodes in order' do
|
37
|
+
@tree.insert(:e, 3)
|
38
|
+
@tree.insert(:d, 3)
|
39
|
+
@tree.insert(:c, 3)
|
40
|
+
@tree.map(&:key).must_equal [:a, :b, :c, :d, :e]
|
41
|
+
end
|
42
|
+
|
43
|
+
it '#to_h converts tree to Hash' do
|
44
|
+
@tree.to_h.must_equal a: 1, b: 2
|
45
|
+
end
|
46
|
+
end
|