ds 0.0.4 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +11 -0
  3. data/.rubocop_todo.yml +452 -0
  4. data/.travis.yml +12 -0
  5. data/Gemfile +1 -1
  6. data/README.rdoc +185 -214
  7. data/Rakefile +8 -3
  8. data/ds.gemspec +16 -13
  9. data/lib/ds.rb +20 -30
  10. data/lib/ds/{matrixes → arrays}/array_2d.rb +9 -10
  11. data/lib/ds/arrays/expandable_array.rb +34 -0
  12. data/lib/ds/arrays/heap_store.rb +32 -0
  13. data/lib/ds/arrays/tri_matrix.rb +33 -0
  14. data/lib/ds/lists/list.rb +310 -186
  15. data/lib/ds/lists/list_element.rb +14 -11
  16. data/lib/ds/pair.rb +4 -4
  17. data/lib/ds/queues/priority_queue.rb +33 -20
  18. data/lib/ds/queues/simple_queue.rb +55 -0
  19. data/lib/ds/sets/indexed_set.rb +37 -0
  20. data/lib/ds/stacks/stack.rb +25 -17
  21. data/lib/ds/trees/binary_heap.rb +71 -66
  22. data/lib/ds/trees/binary_tree.rb +40 -44
  23. data/lib/ds/trees/red_black_tree.rb +123 -0
  24. data/lib/ds/trees/red_black_tree/node.rb +21 -0
  25. data/lib/ds/trees/tree.rb +50 -48
  26. data/lib/ds/trees/tree_walker.rb +73 -144
  27. data/lib/ds/trees/trie.rb +67 -37
  28. data/lib/ds/trees/trie/node.rb +48 -0
  29. data/lib/ds/version.rb +2 -1
  30. data/test/help.rb +3 -6
  31. data/test/performance/binary_heap_performance_test.rb +20 -0
  32. data/test/performance/list_performance_test.rb +36 -0
  33. data/test/performance/priority_queue_performance.rb +32 -0
  34. data/test/performance/rbt_performance_test.rb +17 -0
  35. data/test/performance/simple_queue_performance_test.rb +37 -0
  36. data/test/performance/stack_test.rb +45 -0
  37. data/test/test_array2d.rb +29 -31
  38. data/test/test_binary_heap.rb +29 -23
  39. data/test/test_binary_tree.rb +30 -20
  40. data/test/test_expandable_array.rb +6 -10
  41. data/test/test_heap_store.rb +34 -0
  42. data/test/test_indexed_set.rb +26 -0
  43. data/test/test_list.rb +226 -109
  44. data/test/test_list_element.rb +34 -16
  45. data/test/test_pair.rb +5 -8
  46. data/test/test_priority_queue.rb +43 -64
  47. data/test/test_queue.rb +12 -61
  48. data/test/test_red_black_tree.rb +46 -0
  49. data/test/test_stack.rb +35 -39
  50. data/test/test_tree.rb +42 -29
  51. data/test/test_tree_walker.rb +27 -52
  52. data/test/test_tri_matrix.rb +6 -11
  53. data/test/test_trie.rb +59 -17
  54. metadata +80 -35
  55. data/lib/ds/ext/array_x.rb +0 -35
  56. data/lib/ds/graphs/digraph.rb +0 -20
  57. data/lib/ds/graphs/edge.rb +0 -15
  58. data/lib/ds/graphs/graph.rb +0 -111
  59. data/lib/ds/graphs/graph_as_matrix.rb +0 -113
  60. data/lib/ds/graphs/graph_as_tri_matrix.rb +0 -24
  61. data/lib/ds/lists/cyclic_list.rb +0 -21
  62. data/lib/ds/lists/ring.rb +0 -42
  63. data/lib/ds/matrixes/expandable_array.rb +0 -37
  64. data/lib/ds/matrixes/tri_matrix.rb +0 -30
  65. data/lib/ds/queues/queue.rb +0 -53
  66. data/lib/ds/sets/ordered_set.rb +0 -32
  67. data/lib/ds/trees/binary_search_tree.rb +0 -34
  68. data/lib/ds/trees/complete_binary_tree.rb +0 -60
  69. data/test/test_array_x.rb +0 -51
  70. data/test/test_binary_search_tree.rb +0 -39
  71. data/test/test_complete_binary_tree.rb +0 -58
  72. data/test/test_digraph.rb +0 -134
  73. data/test/test_graph.rb +0 -80
  74. data/test/test_ordered_set.rb +0 -28
  75. data/test/test_ring.rb +0 -28
@@ -1,85 +1,81 @@
1
1
  require 'help'
2
2
 
3
- describe Stack do
4
-
3
+ describe Stack do
5
4
  before do
6
- @stack = Stack.new
7
- @stack.push :first
8
- @stack.push :second
5
+ @stack = Stack.new(:first, :second)
9
6
  end
10
7
 
11
- describe "Empty stack" do
12
-
8
+ describe 'Empty stack' do
13
9
  before do
14
10
  @empty_stack = Stack.new
15
11
  end
16
12
 
17
- it "should be empty." do
13
+ it 'should be empty.' do
18
14
  assert @empty_stack.empty?
19
15
  @empty_stack.size.must_equal 0
20
16
  end
21
17
 
22
- it "#pop should retrun nil." do
18
+ it '#pop should retrun nil.' do
23
19
  @empty_stack.pop.must_be_nil
24
20
  end
25
21
 
26
- it "#peek should return nil." do
27
- @empty_stack.peek.must_be_nil
22
+ it '#peek should return nil.' do
23
+ @empty_stack.peek.must_be_nil
28
24
  end
29
25
 
30
- it "#push should change stack size." do
26
+ it '#push should change stack size.' do
31
27
  @empty_stack.push :first
32
28
  refute @empty_stack.empty?
33
29
  @empty_stack.size.must_equal 1
34
30
  end
35
31
  end
36
32
 
33
+ describe 'Not empty stack implemented as List' do
34
+ before do
35
+ @stack = Stack.create(:first, :second)
36
+ end
37
37
 
38
- describe "Not empty stack" do
39
-
40
- it "should not be empty." do
38
+ it 'should not be empty.' do
41
39
  refute @stack.empty?
42
40
  end
43
41
 
44
- it "#peek should return element from the top of the stack." do
42
+ it '#peek should return element from the top of the stack.' do
45
43
  @stack.peek.must_equal :second
46
44
  end
47
45
 
48
- it "#pop should remove element form the top of the stack." do
49
- @stack.pop
46
+ it '#pop should remove element form the top of the stack.' do
47
+ last = @stack.pop
48
+ last.must_equal :second
50
49
  @stack.size.must_equal 1
51
50
  @stack.peek.must_equal :first
52
51
  end
53
52
 
54
- it "#push should insert element to the top of the stack." do
53
+ it '#push should insert element to the top of the stack.' do
55
54
  @stack.push(:third)
56
55
  @stack.peek.must_equal :third
57
56
  @stack.size.must_equal 3
58
57
  end
58
+ end
59
59
 
60
- if ENV['BENCH']
61
- describe "performance" do
62
-
63
- before do
64
- 100000.times do |n|
65
- @stack.push 4
66
- end
67
- end
60
+ describe 'Not empty stack implemented as Array' do
61
+ it 'should not be empty.' do
62
+ refute @stack.empty?
63
+ end
68
64
 
69
- bench_performance_constant "#pop should be const operation.", 0.999 do |n|
70
- n.times do
71
- @stack.pop
72
- end
73
- end
65
+ it '#peek should return element from the top of the stack.' do
66
+ @stack.peek.must_equal :second
67
+ end
74
68
 
75
- bench_performance_constant "#push should be const operation.", 0.999 do |n|
76
- n.times do
77
- @stack.push 3
78
- end
79
- end
69
+ it '#pop should remove element form the top of the stack.' do
70
+ @stack.pop
71
+ @stack.size.must_equal 1
72
+ @stack.peek.must_equal :first
73
+ end
80
74
 
81
- end
75
+ it '#push should insert element to the top of the stack.' do
76
+ @stack.push(:third)
77
+ @stack.peek.must_equal :third
78
+ @stack.size.must_equal 3
82
79
  end
83
80
  end
84
81
  end
85
-
@@ -1,71 +1,84 @@
1
1
  require 'help'
2
2
 
3
3
  describe Tree do
4
-
5
4
  before do
6
5
  t = Tree.new(2)
7
- c1 = t << 5
8
- c2 = t << 8
9
- t << 9
6
+ @child1 = t << 5
7
+ @child2 = t << 8
8
+ @child3 = t << 9
10
9
 
11
- c1 << 4
12
- c1 << 10
13
- c2 << 3
10
+ @grand1 = @child1 << 4
11
+ @grand2 = @child1 << 10
12
+ @grand3 = @child2 << 3
14
13
 
15
14
  @tree = t
16
15
  end
17
-
18
- it "#to_a should return tree converted to array." do
19
- @tree.to_a.must_equal [2,5,8,9,4,10,3]
16
+
17
+ it '#to_a should return tree converted to array.' do
18
+ @tree.to_a.must_equal [2, 5, 8, 9, 4, 10, 3]
20
19
  end
21
20
 
22
- it "<< should add new subtree to tree." do
21
+ it '<< should add new subtree to tree.' do
23
22
  subtree = @tree << 7
24
23
  subtree.must_be_kind_of Tree
25
24
  @tree.children.size.must_equal 4
26
25
  end
27
26
 
28
- it "#leaf? should check if node is a leaf." do
27
+ it '#parent should return node parent' do
28
+ @child1.parent.must_equal @tree
29
+ @child2.parent.must_equal @tree
30
+ @grand1.parent.must_equal @child1
31
+ @grand3.parent.must_equal @child2
32
+ end
33
+
34
+ it '#sibblings should return node sibblings' do
35
+ @child1.sibblings.must_equal [@child2, @child3]
36
+ @child2.sibblings.must_equal [@child1, @child3]
37
+ @grand1.sibblings.must_equal [@grand2]
38
+ @grand3.sibblings.must_equal []
39
+ end
40
+
41
+ it '#leaf? should check if node is a leaf.' do
29
42
  refute @tree.leaf?
30
43
  assert @tree.children.last.leaf?
31
44
  end
32
45
 
33
- it "#get_leaves should return list of tree leaves." do
46
+ it '#children returns node child nodes.' do
47
+ @tree.children.map(&:data).must_equal([5, 8, 9])
48
+ end
49
+
50
+ it '#get_leaves should return list of tree leaves.' do
34
51
  leaves = @tree.get_leaves
35
52
  leaves.must_be_kind_of List
36
- leaves.to_a.collect{ |e| e.data }.must_equal [4,10,3,9]
53
+ leaves.to_a.collect(&:data).must_equal [4, 10, 3, 9]
37
54
  end
38
55
 
39
- it "#leaf_count should return number of tree leaves." do
56
+ it '#leaf_count should return number of tree leaves.' do
40
57
  @tree.leaf_count.must_equal 4
41
58
  end
42
59
 
43
- it "#levels should return number of nodes on each tree level." do
44
- @tree.levels.must_equal 1 => 1, 2 => 3, 3 => 3
60
+ it '#levels should return number of nodes on each tree level.' do
61
+ @tree.levels.must_equal 1 => 1, 2 => 3, 3 => 3
45
62
  end
46
63
 
47
-
48
- it "#height should return tree height." do
64
+ it '#height should return tree height.' do
49
65
  @tree.height.must_equal 3
50
66
  end
51
67
 
52
- it "Tree.h should return subtree height." do
68
+ it 'Tree.h should return subtree height.' do
53
69
  Tree.h(@tree.children.last).must_equal 1
54
70
  end
55
71
 
56
- it "#width should return tree width." do
72
+ it '#width should return tree width.' do
57
73
  @tree.width.must_equal 3
58
74
  end
59
75
 
60
-
61
- it "#lowest_height should return node which lies closest to the root." do
62
- @tree.lowest_height.data.must_equal 9
76
+ it '#lowest_height should return node which lies closest to the root.' do
77
+ @tree.lowest_height.data.must_equal 9
63
78
  end
64
79
 
65
- it "#mirror! should mirror tree." do
66
- @tree.mirror!
67
- @tree.to_a.must_equal [2,9,8,5,3,10,4]
80
+ it '#mirror! should mirror tree.' do
81
+ @tree.mirror!
82
+ @tree.to_a.must_equal [2, 9, 8, 5, 3, 10, 4]
68
83
  end
69
-
70
84
  end
71
-
@@ -1,91 +1,66 @@
1
- require "help"
1
+ require 'help'
2
2
 
3
3
  describe TreeWalker do
4
-
5
- describe "traversing Tree" do
6
-
4
+ describe 'traversing Tree' do
7
5
  before do
8
-
9
6
  t = Tree.new(2)
10
7
  c1 = t << 5
11
8
  c2 = t << 8
12
9
  t << 9
13
-
14
10
  c1 << 4
15
11
  c1 << 10
16
12
  c2 << 3
17
13
 
18
14
  @tree = t
19
-
20
- @walker = TreeWalker.new(@tree)
15
+ @walker = TreeWalker.new(@tree)
21
16
  end
22
17
 
23
-
24
- it "#traverse without arguments should traverse tree in BFS order." do
25
- @walker.traverse.must_equal [2,5,8,9,4,10,3]
18
+ it '#traverse without arguments should traverse tree in BFS order.' do
19
+ @walker.traverse.must_equal [2, 5, 8, 9, 4, 10, 3]
26
20
  end
27
21
 
28
- it "should traverse in BFS order." do
29
- @walker.traverse(:bfs).must_equal [2,5,8,9,4,10,3]
30
- end
31
-
32
- it "#summarize should transform tree." do
33
- @walker.summarize(:topdown).to_a.must_equal [2,7,10,11,11,17,13]
22
+ it 'should traverse in BFS order.' do
23
+ @walker.traverse(:bfs).must_equal [2, 5, 8, 9, 4, 10, 3]
34
24
  end
35
25
  end
36
26
 
37
- describe "traversing Binary Tree" do
38
-
27
+ describe 'traversing Binary Tree' do
39
28
  before do
40
29
  @bin_tree = BinaryTree.new
41
- [2,5,8,9,11,12,14].each{|x| @bin_tree.insert(x)}
42
- @bin_walker = TreeWalker.new(@bin_tree)
30
+ [2, 5, 8, 9, 11, 12, 14].each { |x| @bin_tree.insert(x) }
31
+ @bin_walker = TreeWalker.new(@bin_tree)
43
32
  end
44
33
 
45
- it "#traverse without arguments should traverse tree in BFS order." do
46
- @bin_walker.traverse.must_equal [2,5,8,9,11,12,14]
34
+ it '#traverse without arguments should traverse tree in BFS order.' do
35
+ @bin_walker.traverse.must_equal [2, 5, 8, 9, 11, 12, 14]
47
36
  end
48
37
 
49
- it "should traverse in BFS order." do
50
- @bin_walker.traverse(:bfs).must_equal [2,5,8,9,11,12,14]
51
-
38
+ it 'should traverse in BFS order.' do
39
+ @bin_walker.traverse(:bfs).must_equal [2, 5, 8, 9, 11, 12, 14]
52
40
  end
53
41
 
54
- it "should traverse in preorder." do
55
- @bin_walker.traverse(:preorder).must_equal [2,5,9,11,8,12,14]
42
+ it 'should traverse in preorder.' do
43
+ @bin_walker.traverse(:preorder).must_equal [2, 5, 9, 11, 8, 12, 14]
56
44
 
57
45
  arr = []
58
- @bin_walker.traverse(:preorder){|t| arr << t.data}
59
- arr.must_equal [2,5,9,11,8,12,14]
46
+ @bin_walker.traverse(:preorder) { |t| arr << t.data }
47
+ arr.must_equal [2, 5, 9, 11, 8, 12, 14]
60
48
  end
61
49
 
62
-
63
- it "should traverse in postorder." do
64
- @bin_walker.traverse(:postorder).must_equal [9,11,5,12,14,8,2]
50
+ it 'should traverse in postorder.' do
51
+ @bin_walker.traverse(:postorder).must_equal [9, 11, 5, 12, 14, 8, 2]
65
52
 
66
53
  arr = []
67
- @bin_walker.traverse(:postorder){|t| arr << t.data}
68
- arr.must_equal [9,11,5,12,14,8,2]
54
+ @bin_walker.traverse(:postorder) { |t| arr << t.data }
55
+ arr.must_equal [9, 11, 5, 12, 14, 8, 2]
69
56
  end
70
57
 
71
- it "should traverse in inorder." do
72
- @bin_walker.traverse(:inorder).must_equal [9,5,11,2,12,8,14]
73
-
74
- arr = []
75
- @bin_walker.traverse(:inorder){|t| arr << t.data}
76
- arr.must_equal [9,5,11,2,12,8,14]
77
- end
78
-
79
- it "#summarize should transform tree." do
80
- @bin_walker.summarize(:bottomup).to_a.must_equal [61,25,34,9,11,12,14]
81
- end
58
+ it 'should traverse in inorder.' do
59
+ @bin_walker.traverse(:inorder).must_equal [9, 5, 11, 2, 12, 8, 14]
82
60
 
83
- it "recalculate! should change values of tree nodes." do
84
- @bin_walker.summarize(:inorder).to_a.must_equal [2,5,10,9,16,14,24]
61
+ arr = []
62
+ @bin_walker.traverse(:inorder) { |t| arr << t.data }
63
+ arr.must_equal [9, 5, 11, 2, 12, 8, 14]
85
64
  end
86
-
87
65
  end
88
66
  end
89
-
90
-
91
-
@@ -1,22 +1,17 @@
1
1
  require 'help'
2
2
 
3
3
  describe TriMatrix do
4
-
5
4
  before do
6
5
  @tri_matrix = TriMatrix.new
7
- @tri_matrix[0,1] = true
8
- @tri_matrix[0,2] = true
6
+ @tri_matrix[0, 1] = true
7
+ @tri_matrix[0, 2] = true
9
8
  end
10
9
 
11
-
12
- it "[x,y] should be same as [y,x]" do
13
- @tri_matrix[0,1].must_be_same_as @tri_matrix[1,0]
10
+ it '[x,y] should be same as [y,x]' do
11
+ @tri_matrix[0, 1].must_be_same_as @tri_matrix[1, 0]
14
12
  end
15
13
 
16
- it "should store elements in array" do
17
- @tri_matrix.to_a.must_equal [0,true,0,true]
14
+ it 'should store elements in array' do
15
+ @tri_matrix.to_a.must_equal [0, true, 0, true]
18
16
  end
19
-
20
17
  end
21
-
22
-
@@ -1,32 +1,74 @@
1
1
  require 'help'
2
2
 
3
3
  describe Trie do
4
-
5
4
  before do
6
5
  @trie = Trie.new
7
6
  @dict = Trie.new
8
- @dict.insert("hello")
7
+ @dict.insert('hello')
8
+ end
9
+
10
+ it '#insert should add new string to trie.' do
11
+ @trie.insert('thing')
12
+ assert @trie.find('thing')
13
+
14
+ @trie.insert('think')
15
+ assert @trie.find('thing')
16
+
17
+ @trie.insert('math')
18
+ assert @trie.find('math')
9
19
  end
10
20
 
11
- it "#insert should add new string to trie." do
12
- @trie.insert("thing");
13
- assert @trie.find("thing")
14
-
15
- @trie.insert("think")
16
- assert @trie.find("thing")
17
-
18
- @trie.insert("math")
19
- assert @trie.find("math")
20
-
21
+ it 'has hash like accessors' do
22
+ @trie['thing'] = 'one'
23
+ assert_equal @trie['thing'], 'one'
21
24
  end
22
25
 
23
- it "should not find not added word." do
24
- @dict.find("blah").must_be_nil
26
+ it '#find should not find not added word.' do
27
+ @dict.find('blah').must_be_nil
25
28
  end
26
29
 
27
- it "should raise error if character is not in trie alphabet." do
28
- proc {@dict.find("m%$r")}.must_raise ArgumentError
29
- proc {@dict.insert("m%$r")}.must_raise ArgumentError
30
+ it '#delete removes word from tree' do
31
+ @dict.insert('he')
32
+ @dict.insert('help')
33
+ @dict.delete('hello')
34
+ refute @dict.find('hello')
35
+ refute @dict.find('hellp')
36
+ refute @dict.find('hel')
37
+ assert @dict.find('he')
38
+ assert @dict.find('help')
30
39
  end
31
40
 
41
+ it '#each iterates through trie' do
42
+ @dict.insert('he')
43
+ @dict.insert('help')
44
+ assert_equal @dict.map { |n| n }, %w(he hello help)
45
+ assert_equal @dict.map { |k, v| [k, v] }, [['he', true], ['hello', true], ['help', true]]
46
+ end
47
+
48
+ it '#with_prefix returns words with matching prefix' do
49
+ @dict.insert('help')
50
+ @dict.insert('him')
51
+ assert_equal @dict.with_prefix('he'), %w(hello help)
52
+
53
+ arr = []
54
+ @dict.with_prefix('he') { |n| arr << n }
55
+ assert_equal arr, %w(hello help)
56
+
57
+ assert_equal @dict.with_prefix('yeti'), []
58
+ end
59
+
60
+ it '#to_h converts tree to Hash' do
61
+ @dict.to_h.must_equal 'hello' => true
62
+ end
63
+
64
+ it '#alphabet= sets Trie alphabet' do
65
+ @trie = Trie.new
66
+ @trie.alphabet = %w(a b c d)
67
+ proc { @trie.insert('thing') }.must_raise ArgumentError
68
+ end
69
+
70
+ it 'should raise error if character is not in trie alphabet.' do
71
+ proc { @dict.find('m%$r') }.must_raise ArgumentError
72
+ proc { @dict.insert('m%$r') }.must_raise ArgumentError
73
+ end
32
74
  end