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_binary_heap.rb
CHANGED
@@ -1,53 +1,59 @@
|
|
1
|
-
require
|
1
|
+
require 'help'
|
2
2
|
|
3
3
|
describe BinaryHeap do
|
4
|
-
|
5
4
|
before do
|
6
|
-
@arr = [9,8,4,5,11,6]
|
7
|
-
@arr2 = [4,2,9,11,3,5,1]
|
5
|
+
@arr = [9, 8, 4, 5, 11, 6]
|
6
|
+
@arr2 = [4, 2, 9, 11, 3, 5, 1]
|
8
7
|
@heap = BinaryHeap.new(*@arr)
|
9
8
|
@heap2 = BinaryHeap.max(*@arr2)
|
10
9
|
end
|
11
10
|
|
12
|
-
it
|
13
|
-
@heap.to_a.must_equal [11,9,6,5,8,4]
|
14
|
-
@heap2.to_a.must_equal [11,4,9,2,3,5,1]
|
11
|
+
it 'should create heap from array' do
|
12
|
+
@heap.to_a.must_equal [11, 9, 6, 5, 8, 4]
|
13
|
+
@heap2.to_a.must_equal [11, 4, 9, 2, 3, 5, 1]
|
14
|
+
end
|
15
|
+
|
16
|
+
it '#insert should insert new element to the heap maintaining heap relation.' do
|
17
|
+
@heap.size.must_equal 6
|
18
|
+
@heap.insert(13).to_a.must_equal [13, 9, 11, 5, 8, 4, 6]
|
19
|
+
@heap.size.must_equal 7
|
15
20
|
end
|
16
21
|
|
17
|
-
it
|
18
|
-
@heap.
|
22
|
+
it '#top should return max or min heap element' do
|
23
|
+
@heap.top.must_equal 11
|
24
|
+
@heap.shift
|
25
|
+
@heap.top.must_equal 9
|
19
26
|
end
|
20
27
|
|
21
|
-
it
|
28
|
+
it '#shift should remove element from heap maintaining heap relation.' do
|
22
29
|
@heap.shift.must_equal 11
|
23
|
-
@heap.to_a.must_equal [9,8,6,5,4]
|
30
|
+
@heap.to_a.must_equal [9, 8, 6, 5, 4]
|
24
31
|
@heap.shift.must_equal 9
|
25
|
-
@heap.to_a.must_equal [8,5,6,4]
|
32
|
+
@heap.to_a.must_equal [8, 5, 6, 4]
|
26
33
|
@heap.shift.must_equal 8
|
27
|
-
@heap.to_a.must_equal [6,5,4]
|
34
|
+
@heap.to_a.must_equal [6, 5, 4]
|
28
35
|
@heap.shift.must_equal 6
|
29
|
-
@heap.to_a.must_equal [5,4]
|
36
|
+
@heap.to_a.must_equal [5, 4]
|
30
37
|
@heap.shift.must_equal 5
|
31
38
|
@heap.to_a.must_equal [4]
|
32
39
|
@heap.shift.must_equal 4
|
33
40
|
@heap.shift.must_be_nil
|
34
41
|
end
|
35
42
|
|
36
|
-
describe
|
37
|
-
|
43
|
+
describe 'Minimal Heap' do
|
38
44
|
before do
|
39
|
-
@min_heap = BinaryHeap.new(*@arr){|parent,child| parent < child}
|
45
|
+
@min_heap = BinaryHeap.new(*@arr) { |parent, child| parent < child }
|
40
46
|
@min_heap2 = BinaryHeap.min(*@arr)
|
41
47
|
end
|
42
48
|
|
43
|
-
it
|
44
|
-
@min_heap.to_a.must_equal [4,5,6,8,11,9]
|
45
|
-
@min_heap2.to_a.must_equal [4,5,6,8,11,9]
|
49
|
+
it 'should create heap from array.' do
|
50
|
+
@min_heap.to_a.must_equal [4, 5, 6, 8, 11, 9]
|
51
|
+
@min_heap2.to_a.must_equal [4, 5, 6, 8, 11, 9]
|
46
52
|
end
|
47
53
|
|
48
|
-
it
|
49
|
-
@min_heap.insert(3).to_a.must_equal [3,5,4,8,11,9,6]
|
50
|
-
@min_heap2.insert(3).to_a.must_equal [3,5,4,8,11,9,6]
|
54
|
+
it '#insert should insert new element to the heap maintaining heap relation.' do
|
55
|
+
@min_heap.insert(3).to_a.must_equal [3, 5, 4, 8, 11, 9, 6]
|
56
|
+
@min_heap2.insert(3).to_a.must_equal [3, 5, 4, 8, 11, 9, 6]
|
51
57
|
end
|
52
58
|
end
|
53
59
|
end
|
data/test/test_binary_tree.rb
CHANGED
@@ -1,57 +1,67 @@
|
|
1
1
|
require 'help'
|
2
2
|
|
3
3
|
describe BinaryTree do
|
4
|
-
|
5
4
|
before do
|
6
|
-
|
7
5
|
@bin_tree = BinaryTree.new
|
8
|
-
[2,5,8,9,11,12,14].each{|x| @bin_tree.insert(x)}
|
6
|
+
[2, 5, 8, 9, 11, 12, 14].each { |x| @bin_tree.insert(x) }
|
9
7
|
|
10
8
|
@izo_tree = BinaryTree.new
|
11
|
-
[2,7,8,3,11,12,14].each{|x| @izo_tree.insert(x)}
|
9
|
+
[2, 7, 8, 3, 11, 12, 14].each { |x| @izo_tree.insert(x) }
|
12
10
|
|
13
11
|
@small_tree = BinaryTree.new(2)
|
14
12
|
@small_tree << BinaryTree.new(7)
|
15
13
|
@small_tree << BinaryTree.new(8)
|
16
14
|
|
17
15
|
@bin_walker = TreeWalker.new(@bin_tree)
|
16
|
+
end
|
18
17
|
|
18
|
+
it '#to_a should return tree converted to array.' do
|
19
|
+
@bin_tree.to_a.must_equal [2, 5, 8, 9, 11, 12, 14]
|
19
20
|
end
|
20
|
-
|
21
|
-
it
|
22
|
-
@
|
21
|
+
|
22
|
+
it '#parent should return node parent' do
|
23
|
+
@small_tree.parent.must_equal nil
|
24
|
+
@small_tree.right.parent.must_equal @small_tree
|
25
|
+
@bin_tree.right.parent.must_equal @bin_tree
|
23
26
|
end
|
24
27
|
|
25
|
-
it
|
28
|
+
it '#sibblings should return node sibblings' do
|
29
|
+
r = @small_tree.right
|
30
|
+
l = @small_tree.left
|
31
|
+
r.sibblings.must_equal [l]
|
32
|
+
r = @bin_tree.right
|
33
|
+
l = @bin_tree.left
|
34
|
+
r.sibblings.must_equal [l]
|
35
|
+
end
|
36
|
+
|
37
|
+
it '#height should return tree height.' do
|
26
38
|
@bin_tree.height.must_equal 3
|
27
39
|
end
|
28
40
|
|
29
|
-
it
|
41
|
+
it '#width should return tree width.' do
|
30
42
|
@bin_tree.width.must_equal 4
|
31
43
|
end
|
32
44
|
|
33
|
-
it
|
45
|
+
it '#leaf_count should return number of tree leaves.' do
|
34
46
|
@bin_tree.leaf_count.must_equal 4
|
35
47
|
end
|
36
|
-
|
37
|
-
it
|
38
|
-
@bin_tree.get_leaves.to_a.collect
|
48
|
+
|
49
|
+
it '#get_leaves should return list of tree leaves.' do
|
50
|
+
@bin_tree.get_leaves.to_a.collect(&:data).must_equal [9, 11, 12, 14]
|
39
51
|
end
|
40
52
|
|
41
|
-
it
|
42
|
-
assert @bin_tree.lowest_height.data.must_equal 9
|
53
|
+
it '#lowest_height should return node which lies closest to the root.' do
|
54
|
+
assert @bin_tree.lowest_height.data.must_equal 9
|
43
55
|
end
|
44
56
|
|
45
|
-
it
|
57
|
+
it '#mirror should mirror tree.' do
|
46
58
|
@bin_tree.mirror!
|
47
|
-
@bin_tree.to_a.must_equal [2,8,5,14,12,11,9]
|
59
|
+
@bin_tree.to_a.must_equal [2, 8, 5, 14, 12, 11, 9]
|
48
60
|
end
|
49
61
|
|
50
|
-
it
|
62
|
+
it '#isometric should check if tree is isometric to antother.' do
|
51
63
|
assert @bin_tree.izometric?(@izo_tree)
|
52
64
|
assert @izo_tree.izometric?(@bin_tree)
|
53
65
|
refute @bin_tree.izometric?(@small_tree)
|
54
66
|
end
|
55
|
-
|
56
67
|
end
|
57
|
-
|
@@ -1,26 +1,22 @@
|
|
1
1
|
require 'help'
|
2
2
|
|
3
3
|
describe ExpandableArray do
|
4
|
-
|
5
|
-
describe "Zero Array" do
|
6
|
-
|
4
|
+
describe 'Zero Array' do
|
7
5
|
before do
|
8
|
-
@zero_arr = ExpandableArray.new(0,0)
|
6
|
+
@zero_arr = ExpandableArray.new(0, 0)
|
9
7
|
@zero_arr[0] = 1
|
10
8
|
end
|
11
9
|
|
12
|
-
it
|
10
|
+
it 'access to element x should set all elements from array size to x to zero.' do
|
13
11
|
@zero_arr.size.must_equal 1
|
14
12
|
@zero_arr[3].must_equal 0
|
15
13
|
@zero_arr.size.must_equal 4
|
16
|
-
@zero_arr.must_equal [1,0,0,0]
|
14
|
+
@zero_arr.must_equal [1, 0, 0, 0]
|
17
15
|
end
|
18
16
|
|
19
|
-
it
|
17
|
+
it 'setting value on index x should set all elements from array size to x to zero.' do
|
20
18
|
@zero_arr[5] = 2
|
21
|
-
@zero_arr.must_equal [1,0,0,0,0,2]
|
19
|
+
@zero_arr.must_equal [1, 0, 0, 0, 0, 2]
|
22
20
|
end
|
23
21
|
end
|
24
22
|
end
|
25
|
-
|
26
|
-
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'help'
|
2
|
+
|
3
|
+
describe HeapStore do
|
4
|
+
before do
|
5
|
+
@store = HeapStore.new(1, 2, 3, 4, 5, 6, 7)
|
6
|
+
end
|
7
|
+
|
8
|
+
it '#size returns store size.' do
|
9
|
+
@store.size.must_equal 7
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'indexing starts form one.' do
|
13
|
+
@store[1].must_equal 1
|
14
|
+
end
|
15
|
+
|
16
|
+
it '#first returns element on index 1.' do
|
17
|
+
@store.first.must_equal 1
|
18
|
+
end
|
19
|
+
|
20
|
+
it '#pop removes last element.' do
|
21
|
+
@store.pop.must_equal 7
|
22
|
+
@store.size.must_equal 6
|
23
|
+
end
|
24
|
+
|
25
|
+
it '#push adds element to store.' do
|
26
|
+
@store.push 11
|
27
|
+
@store.size.must_equal 8
|
28
|
+
end
|
29
|
+
|
30
|
+
it '#to_a returns array representation.' do
|
31
|
+
@store.to_a.must_equal [1, 2, 3, 4, 5, 6, 7]
|
32
|
+
@store.to_a.must_be_kind_of Array
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'help'
|
2
|
+
|
3
|
+
describe 'IndexedSet' do
|
4
|
+
before do
|
5
|
+
@set = IndexedSet.new
|
6
|
+
@set.push(:first)
|
7
|
+
end
|
8
|
+
|
9
|
+
it '#push should add new element to set and return its index.' do
|
10
|
+
@set.push(:second).must_equal 1
|
11
|
+
@set.push(:first).must_equal 0
|
12
|
+
end
|
13
|
+
|
14
|
+
it '#index should return element index.' do
|
15
|
+
@set.index(:first).must_equal 0
|
16
|
+
@set.push(:second)
|
17
|
+
@set.index(:second).must_equal 1
|
18
|
+
@set.index(:non_exist).must_be_nil
|
19
|
+
end
|
20
|
+
|
21
|
+
it '#to_a should return array.' do
|
22
|
+
@set.push(:second)
|
23
|
+
@set.push(:third)
|
24
|
+
@set.to_a.must_equal [:first, :second, :third]
|
25
|
+
end
|
26
|
+
end
|
data/test/test_list.rb
CHANGED
@@ -1,195 +1,312 @@
|
|
1
1
|
require 'help'
|
2
2
|
|
3
3
|
describe List do
|
4
|
-
|
5
4
|
before do
|
6
|
-
@list = List.
|
7
|
-
@list2 = List.
|
5
|
+
@list = List.new(1, 2, 3, 4)
|
6
|
+
@list2 = List.new(4, 5, 7)
|
7
|
+
@empty_list = List.new
|
8
|
+
@numbers = List.new(*(1..10).to_a)
|
9
|
+
@even_numbers = List.new(2, 4, 6, 8, 10)
|
10
|
+
end
|
8
11
|
|
9
|
-
|
10
|
-
|
12
|
+
describe 'Empty list' do
|
13
|
+
it '#empty? should be true' do
|
14
|
+
assert @empty_list.empty?
|
15
|
+
end
|
16
|
+
|
17
|
+
it '#append should add element to list' do
|
18
|
+
@empty_list.append(8)
|
19
|
+
@empty_list.to_a.must_equal [8]
|
20
|
+
end
|
21
|
+
|
22
|
+
it '#unshift should add element to list' do
|
23
|
+
@empty_list.unshift(8)
|
24
|
+
@empty_list.to_a.must_equal [8]
|
25
|
+
end
|
26
|
+
|
27
|
+
it '#shift raises exception' do
|
28
|
+
proc { @empty_list.shift }.must_raise ListError
|
29
|
+
end
|
11
30
|
end
|
12
31
|
|
13
|
-
it
|
14
|
-
@list.must_be_kind_of List
|
32
|
+
it '#from_array should transform array to list.' do
|
33
|
+
@list.must_be_kind_of List
|
15
34
|
@list.length.must_equal 4
|
16
35
|
end
|
17
36
|
|
18
|
-
it
|
37
|
+
it '#clone returns new list with identical values' do
|
38
|
+
cloned = @list.clone
|
39
|
+
cloned.must_be_kind_of List
|
40
|
+
cloned.to_a.must_equal [1, 2, 3, 4]
|
41
|
+
@list[0] = 9
|
42
|
+
@list.to_a.must_equal [9, 2, 3, 4]
|
43
|
+
cloned.to_a.must_equal [1, 2, 3, 4]
|
44
|
+
end
|
45
|
+
|
46
|
+
it '#clear resets lists' do
|
47
|
+
@list.clear
|
48
|
+
@list.must_be_kind_of List
|
49
|
+
@list.to_a.must_equal []
|
50
|
+
@list.size.must_equal 0
|
51
|
+
end
|
52
|
+
|
53
|
+
it '#length should return list size.' do
|
19
54
|
@list.length.must_equal 4
|
20
55
|
@list2.length.must_equal 3
|
21
56
|
end
|
22
57
|
|
58
|
+
it '#get should return list element if element is on the list' do
|
59
|
+
x = @list.head.next
|
60
|
+
found = @list.get(x)
|
61
|
+
found.must_be_kind_of ListElement
|
62
|
+
end
|
63
|
+
|
64
|
+
it '#get! should raise error if element is not found on the list' do
|
65
|
+
x = @list2.head.next
|
66
|
+
proc { @list.get!(x) }.must_raise ListError
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'at returns element on given index' do
|
70
|
+
@list.at(2).data.must_equal 3
|
71
|
+
@list2.at(2).data.must_equal 7
|
72
|
+
@list.at(42).must_equal nil
|
73
|
+
@list.at(-1).data.must_equal 4
|
74
|
+
@list.at(-2).data.must_equal 3
|
75
|
+
@list.at(-4).data.must_equal 1
|
76
|
+
@list.at(-42).must_equal nil
|
77
|
+
end
|
78
|
+
|
79
|
+
it '#[] returns element on given index' do
|
80
|
+
@list[2].data.must_equal 3
|
81
|
+
@list2[2].data.must_equal 7
|
82
|
+
|
83
|
+
@list[1..2].map(&:data).must_equal [2, 3]
|
84
|
+
@list[1..8].map(&:data).must_equal [2, 3, 4]
|
85
|
+
@list[1, 2].map(&:data).must_equal [2, 3]
|
86
|
+
@list[1, 3].map(&:data).must_equal [2, 3, 4]
|
87
|
+
@list[2, 8].map(&:data).must_equal [3, 4]
|
88
|
+
end
|
89
|
+
|
90
|
+
it '#[] changes element on given index' do
|
91
|
+
@list[2] = 11
|
92
|
+
@list[2].data.must_equal 11
|
93
|
+
end
|
94
|
+
|
95
|
+
it '#[] replaces elelment with elements on Array' do
|
96
|
+
@list[3] = [0, 0]
|
97
|
+
@list.to_a.must_equal [1, 2, 3, 0, 0]
|
98
|
+
@list.size.must_equal 5
|
99
|
+
end
|
100
|
+
|
101
|
+
it '#[] replaces elements when passed Array and count' do
|
102
|
+
@list[1, 2] = [0, 0]
|
103
|
+
@list.to_a.must_equal [1, 0, 0, 4]
|
104
|
+
@list.size.must_equal 4
|
105
|
+
end
|
106
|
+
|
107
|
+
it '#[] replaces element when passed Array and count on list tail' do
|
108
|
+
@list[1, 3] = [0, 0, 0]
|
109
|
+
@list.to_a.must_equal [1, 0, 0, 0]
|
110
|
+
@list.size.must_equal 4
|
111
|
+
end
|
112
|
+
|
113
|
+
it '#[] replaces element when passed Array and range' do
|
114
|
+
@list[1..2] = [0, 0]
|
115
|
+
@list.to_a.must_equal [1, 0, 0, 4]
|
116
|
+
@list.size.must_equal 4
|
117
|
+
end
|
118
|
+
|
119
|
+
it '#[] should raise error when count or range is invalid' do
|
120
|
+
proc { @list[1, 8] = [0, 0] }.must_raise ListError
|
121
|
+
proc { @list[1, -1] = [0, 0] }.must_raise ListError
|
122
|
+
proc { @list[1..-1] = [0, 0] }.must_raise ListError
|
123
|
+
proc { @list[1..90] = [0, 0] }.must_raise ListError
|
124
|
+
proc { @list[1, 4] = [0, 0] }.must_raise ListError
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'replace element one with other' do
|
128
|
+
list = List.new(8, 9)
|
129
|
+
el = @list.at(2)
|
130
|
+
@list.replace(el, list)
|
131
|
+
@list.to_a.must_equal [1, 2, 8, 9, 4]
|
132
|
+
@list.size.must_equal 5
|
133
|
+
el = @list.at(0)
|
134
|
+
list = List.new(8, 9)
|
135
|
+
@list.replace(el, list)
|
136
|
+
@list.to_a.must_equal [8, 9, 2, 8, 9, 4]
|
137
|
+
@list.size.must_equal 6
|
138
|
+
|
139
|
+
list = List.new(8, 9)
|
140
|
+
el = @list.at(5)
|
141
|
+
@list.replace(el, list)
|
142
|
+
@list.to_a.must_equal [8, 9, 2, 8, 9, 8, 9]
|
143
|
+
@list.size.must_equal 7
|
144
|
+
end
|
145
|
+
|
146
|
+
it '#== returns true only if two lists are equal' do
|
147
|
+
@eq_list = List.new(1, 2, 3, 4)
|
148
|
+
@other_empty = List.new
|
149
|
+
assert @list == @eq_list
|
150
|
+
assert @eq_list == @list
|
151
|
+
refute @list == @empty_list
|
152
|
+
refute @list == @list2
|
153
|
+
assert @empty_list == @other_empty
|
154
|
+
end
|
155
|
+
|
156
|
+
it '#> returns true if first list is grater or longer than second' do
|
157
|
+
@smaller_list = List.new(1, 2, 2, 4)
|
158
|
+
assert @list > @smaller_list
|
159
|
+
@smaller_list2 = List.new(1, 2, 3)
|
160
|
+
assert @list > @smaller_list2
|
161
|
+
end
|
162
|
+
|
163
|
+
it '#< returns true if first list is smaller or shorter than second' do
|
164
|
+
@greater_list = List.new(1, 8, 3, 4)
|
165
|
+
assert @list < @greater_list
|
166
|
+
@greater_list2 = List.new(1, 2, 3, 4, 5)
|
167
|
+
assert @list < @greater_list2
|
168
|
+
end
|
23
169
|
|
24
|
-
it
|
170
|
+
it '#concat should join two lists into one' do
|
171
|
+
sum = @list.concat(@list2)
|
172
|
+
sum.to_a.must_equal [1, 2, 3, 4, 4, 5, 7]
|
173
|
+
assert sum == @list
|
174
|
+
end
|
175
|
+
|
176
|
+
it '#append should add element to the end of the list.' do
|
25
177
|
x = 5
|
26
178
|
@list.append(x)
|
27
179
|
@list.length.must_equal 5
|
28
|
-
@list.last.must_be_same_as x
|
180
|
+
@list.last.must_be_same_as x
|
29
181
|
end
|
30
182
|
|
31
|
-
it
|
183
|
+
it '#unshift should add element at the beginning of the list.' do
|
32
184
|
x = 0
|
33
|
-
@list.
|
185
|
+
@list.unshift(x)
|
34
186
|
@list.length.must_equal 5
|
35
187
|
@list.first.must_be_same_as x
|
36
188
|
end
|
37
189
|
|
38
|
-
it
|
190
|
+
it '#remove should remove element from list.' do
|
39
191
|
second = @list.head.next
|
192
|
+
third = second.next
|
193
|
+
forth = third.next
|
40
194
|
@list.remove(second)
|
41
|
-
@list.to_a.must_equal [1,3,4]
|
195
|
+
@list.to_a.must_equal [1, 3, 4]
|
196
|
+
@list.remove(@list.head)
|
197
|
+
@list.to_a.must_equal [3, 4]
|
198
|
+
@list.remove(forth)
|
199
|
+
@list.to_a.must_equal [3]
|
200
|
+
@list.remove(third)
|
201
|
+
@list.to_a.must_equal []
|
42
202
|
end
|
43
203
|
|
44
|
-
it
|
45
|
-
|
46
|
-
|
47
|
-
@list.
|
204
|
+
it '#pop should remove last list element.' do
|
205
|
+
last = @list.pop
|
206
|
+
last.must_equal 4
|
207
|
+
@list.last.must_equal 3
|
208
|
+
@list.to_a.must_equal [1, 2, 3]
|
209
|
+
end
|
48
210
|
|
49
|
-
|
50
|
-
@list.
|
211
|
+
it '#insert_before should insert new element before another.' do
|
212
|
+
second = @list.head.next
|
213
|
+
@list.insert_before(9, second)
|
214
|
+
@list.to_a.must_equal [1, 9, 2, 3, 4]
|
51
215
|
|
52
|
-
@list.insert_before(
|
53
|
-
@list.to_a.must_equal [8,1,9,2,3,
|
216
|
+
@list.insert_before(8, @list.head)
|
217
|
+
@list.to_a.must_equal [8, 1, 9, 2, 3, 4]
|
54
218
|
|
55
|
-
|
219
|
+
@list.insert_before(7, @list.tail)
|
220
|
+
@list.to_a.must_equal [8, 1, 9, 2, 3, 7, 4]
|
56
221
|
end
|
57
222
|
|
58
|
-
it
|
223
|
+
it '#insert_after should insert new element after another.' do
|
59
224
|
second = @list.head.next
|
60
|
-
@list.insert_after(9,second)
|
61
|
-
@list.to_a.must_equal [1,2,9,3,4]
|
225
|
+
@list.insert_after(9, second)
|
226
|
+
@list.to_a.must_equal [1, 2, 9, 3, 4]
|
62
227
|
|
63
228
|
tail = @list.tail
|
64
|
-
@list.insert_after(11,tail)
|
65
|
-
@list.to_a.must_equal [1,2,9,3,4,11]
|
229
|
+
@list.insert_after(11, tail)
|
230
|
+
@list.to_a.must_equal [1, 2, 9, 3, 4, 11]
|
66
231
|
end
|
67
232
|
|
68
|
-
|
69
|
-
|
70
|
-
@list.head.must_be_kind_of ListElement
|
233
|
+
it '#head should point to first element of the list.' do
|
234
|
+
@list.head.must_be_kind_of ListElement
|
71
235
|
@list2.head.must_be_kind_of ListElement
|
72
236
|
@list.head.data.must_equal 1
|
73
237
|
@list2.head.data.must_equal 4
|
74
238
|
end
|
75
239
|
|
76
|
-
it
|
77
|
-
@list.tail.must_be_kind_of ListElement
|
240
|
+
it '#tail sould point to last element of the list' do
|
241
|
+
@list.tail.must_be_kind_of ListElement
|
78
242
|
@list2.tail.must_be_kind_of ListElement
|
79
|
-
@list.tail.next.must_be_nil
|
243
|
+
@list.tail.next.must_be_nil
|
80
244
|
@list2.tail.next.must_be_nil
|
81
245
|
|
82
246
|
@list.tail.data.must_equal 4
|
83
247
|
@list2.tail.data.must_equal 7
|
84
248
|
end
|
85
249
|
|
86
|
-
it
|
250
|
+
it '#first should return value of the first list element.' do
|
87
251
|
@list.first.must_equal 1
|
88
252
|
@list2.first.must_equal 4
|
89
253
|
end
|
90
254
|
|
91
|
-
|
92
|
-
it "#last should return value of the last list element." do
|
255
|
+
it '#last should return value of the last list element.' do
|
93
256
|
@list.last.must_equal 4
|
94
257
|
@list2.last.must_equal 7
|
95
258
|
end
|
96
259
|
|
97
|
-
it
|
260
|
+
it '#zip? should check if two list are joined.' do
|
98
261
|
refute @list.zip?(@list2)
|
99
262
|
end
|
100
263
|
|
101
|
-
it
|
102
|
-
@list.reverse!.to_a.must_equal [4,3,2,1]
|
103
|
-
@list.reverse!.to_a.must_equal [1,2,3,4]
|
264
|
+
it '#reverse! should reverse list' do
|
265
|
+
@list.reverse!.to_a.must_equal [4, 3, 2, 1]
|
266
|
+
@list.reverse!.to_a.must_equal [1, 2, 3, 4]
|
104
267
|
@list.reverse!.length.must_equal 4
|
105
268
|
end
|
106
269
|
|
107
|
-
it
|
108
|
-
@list2.
|
109
|
-
|
110
|
-
|
111
|
-
it "#merge should be symetric operation." do
|
112
|
-
@list.merge(@list2).to_a.must_equal [1,2,3,4,4,5,7]
|
270
|
+
it '#looped? should check if list has cycle.' do
|
271
|
+
refute @list2.looped?
|
272
|
+
refute @list.looped?
|
113
273
|
end
|
114
274
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
275
|
+
it '#reverse_each should iterate list in reverse order.' do
|
276
|
+
arr = []
|
277
|
+
@list.reverse_each { |e| arr.push e.data }
|
278
|
+
arr.must_equal [4, 3, 2, 1]
|
119
279
|
end
|
120
280
|
|
121
|
-
it
|
122
|
-
|
123
|
-
@
|
124
|
-
|
125
|
-
|
126
|
-
it "#remove! should remove all elements that occur on the other list#2." do
|
127
|
-
@list2.remove!(@list).to_a.must_equal [5,7]
|
281
|
+
it '#each_with_index should iterate list.' do
|
282
|
+
h = {}
|
283
|
+
@list.each_with_index { |e, i| h[i] = e.data }
|
284
|
+
h.must_equal(0 => 1, 1 => 2, 2 => 3, 3 => 4)
|
128
285
|
end
|
129
286
|
|
130
|
-
it
|
131
|
-
|
132
|
-
refute @list.looped?
|
287
|
+
it '#take returns frist n elements form list' do
|
288
|
+
@list.take(2).map(&:data).must_equal [1, 2]
|
133
289
|
end
|
134
290
|
|
135
|
-
it
|
136
|
-
|
137
|
-
@list.each_with_index{|e,i| h[i] = e.data}
|
138
|
-
h.must_equal({0 => 1, 1 => 2, 2 => 3, 3 => 4})
|
291
|
+
it '#to_s should print list in human friendly format.' do
|
292
|
+
@list.to_s.must_equal '1=2=3=4'
|
139
293
|
end
|
140
294
|
|
141
|
-
it
|
142
|
-
@list.map
|
143
|
-
@list.inject(0){ |
|
144
|
-
@list.find { |e| e.data == 1.0
|
295
|
+
it 'should include Enumerable methods.' do
|
296
|
+
@list.map(&:data).must_equal [1, 2, 3, 4]
|
297
|
+
@list.inject(0) { |a, e| a + e.data }.must_equal 10
|
298
|
+
@list.find { |e| e.data == 1.0 }.data.must_equal 1
|
145
299
|
end
|
146
300
|
|
147
|
-
|
148
|
-
describe "Zipped list" do
|
149
|
-
|
301
|
+
describe 'Zipped list' do
|
150
302
|
before do
|
151
303
|
last = @list.tail
|
152
|
-
@zipped = List.
|
304
|
+
@zipped = List.new(1, 2)
|
153
305
|
@zipped.tail = last
|
154
306
|
end
|
155
307
|
|
156
|
-
it
|
308
|
+
it '#zip? should return true' do
|
157
309
|
assert @list.zip?(@zipped)
|
158
310
|
end
|
159
|
-
|
160
|
-
end
|
161
|
-
|
162
|
-
if ENV['BENCH']
|
163
|
-
describe "performance" do
|
164
|
-
|
165
|
-
before do
|
166
|
-
@arr = (1..10_000).to_a.sort_by{rand}
|
167
|
-
|
168
|
-
10000.times do |n|
|
169
|
-
@list.append 4
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
|
174
|
-
bench_performance_constant "#append should be const operation.", 0.999 do |n|
|
175
|
-
n.times do
|
176
|
-
@list.append 3
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
bench_performance_constant "#prepend should be const operation.", 0.999 do |n|
|
181
|
-
n.times do
|
182
|
-
@list.prepend 3
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
bench_performance_linear "#reverse! should be linear operation.", 0.999 do |n|
|
187
|
-
list =List.from_array(@arr[0..n])
|
188
|
-
list.reverse!
|
189
|
-
end
|
190
|
-
|
191
|
-
end
|
192
311
|
end
|
193
|
-
|
194
312
|
end
|
195
|
-
|