ds 0.0.4 → 0.0.6

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.
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,61 +1,91 @@
1
1
  module DS
2
+ # Trie dictionary data structure
2
3
  class Trie < Tree
4
+ attr_accessor :root
3
5
 
4
- ALPHABET = %w{- a b c d e f g h i j k l m n o p q r s t u v w x y z}
6
+ def initialize(value = nil, alphabet = nil)
7
+ @root = Node.new(value)
8
+ self.alphabet = (alphabet || %w(- a b c d e f g h i j k l m n o p q r s t u v w x y z))
9
+ end
10
+
11
+ def alphabet=(arr)
12
+ @alphabet = {}
13
+ arr.each_with_index { |c, i| @alphabet[c] = i }
14
+ end
5
15
 
6
16
  def alphabet
7
- self.class::ALPHABET
17
+ @alphabet.keys
8
18
  end
9
-
10
- def initialize(value=nil)
11
- @children = Array.new(alphabet.size)
12
- @data = value
19
+
20
+ def key(chr)
21
+ @alphabet[chr]
13
22
  end
14
23
 
15
- def insert(s, value=true)
16
- letters = s.scan(/./)
17
- raise ArgumentError, "Not allowed symbol." unless (letters - alphabet).empty?
18
- priv_insert(letters, value)
24
+ def insert(s, value = true)
25
+ letters = get_letters(s)
26
+ root.put(letters, value, self)
27
+ end
28
+
29
+ def []=(k, v)
30
+ insert(k, v)
19
31
  end
20
32
 
21
33
  def find(s)
22
- letters = s.scan(/./)
23
- raise ArgumentError, "Not allowed symbol." unless (letters - alphabet).empty?
24
- priv_find(letters)
34
+ letters = get_letters(s)
35
+ node = root.get(letters, self)
36
+ node.data if node
25
37
  end
26
38
 
27
- protected
28
- def key(chr)
29
- k=alphabet.index(chr)
39
+ def [](k)
40
+ find(k)
30
41
  end
31
42
 
43
+ def delete(s)
44
+ letters = s.scan(/./)
45
+ root.delete(letters, self)
46
+ end
32
47
 
33
- def priv_insert(s, value)
34
- if s.empty?
35
- @data = value
36
- else
37
- index = key(s.first)
38
- subtree = if @children[index]
39
- @children[index]
40
- else
41
- @children[index] = Trie.new
42
- end
43
-
44
- subtree.priv_insert(s[1..-1], value)
48
+ def each(&block)
49
+ visit(root, '', &block)
50
+ end
51
+
52
+ def visit(node, prefix, &block)
53
+ yield prefix, node.data if node.data
54
+ node.children.each_with_index do |n, i|
55
+ visit(n, prefix + alphabet[i], &block) if n
45
56
  end
46
57
  end
47
58
 
48
- def priv_find(search)
49
- if search.empty?
50
- @data
59
+ def with_prefix(prefix, &block)
60
+ letters = get_letters(prefix)
61
+ node = root.get(letters, self)
62
+ if block_given?
63
+ return nil unless node
64
+ visit(node, prefix, &block)
51
65
  else
52
- index = key(search.first)
53
- if @children[index]
54
- @children[index].priv_find(search[1..-1])
55
- else
56
- nil
57
- end
66
+ arr = []
67
+ return arr unless node
68
+ visit(node, prefix) { |n| arr << n }
69
+ arr
58
70
  end
59
71
  end
72
+
73
+ def to_h
74
+ h = {}
75
+ each { |k, v| h[k] = v }
76
+ h
77
+ end
78
+
79
+ private
80
+
81
+ def allowed?(letters)
82
+ (letters - alphabet).empty?
83
+ end
84
+
85
+ def get_letters(s)
86
+ letters = s.scan(/./)
87
+ raise ArgumentError, 'Not allowed symbol.' unless allowed?(letters)
88
+ letters
89
+ end
60
90
  end
61
91
  end
@@ -0,0 +1,48 @@
1
+ module DS
2
+ # Trie dictionary data structure
3
+ class Trie
4
+ # Trie node
5
+ class Node
6
+ attr_reader :children, :data
7
+
8
+ def initialize(value = nil)
9
+ @children = []
10
+ @data = value
11
+ end
12
+
13
+ def put(s, value, trie)
14
+ if s.empty?
15
+ @data = value
16
+ else
17
+ index = trie.key(s.first)
18
+ @children[index] ||= Node.new
19
+ @children[index].put(s[1..-1], value, trie)
20
+ end
21
+ end
22
+
23
+ def get(s, trie)
24
+ if s.empty?
25
+ self
26
+ else
27
+ index = trie.key(s.first)
28
+ @children[index].get(s[1..-1], trie) if @children[index]
29
+ end
30
+ end
31
+
32
+ def delete(s, trie)
33
+ return true if s.empty?
34
+ index = trie.key(s.first)
35
+ flag = @children[index].delete(s[1..-1], trie)
36
+ flag &&= one_child?
37
+ @children[index] = nil if flag
38
+ s.size < 2 ? true : flag && @data.nil?
39
+ end
40
+
41
+ private
42
+
43
+ def one_child?
44
+ @children.compact.size <= 1
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,3 +1,4 @@
1
+ # Main module namespace
1
2
  module DS
2
- VERSION = "0.0.4"
3
+ VERSION = '0.0.6'.freeze
3
4
  end
@@ -1,17 +1,14 @@
1
1
  if ENV['COVERAGE']
2
2
  require 'simplecov'
3
3
  SimpleCov.start do
4
- add_filter "/test/"
4
+ add_filter '/test/'
5
5
  end
6
6
  end
7
7
 
8
-
9
8
  require 'rubygems'
10
- gem 'minitest'
11
9
  require 'minitest/autorun'
12
- require "minitest/benchmark" if ENV['BENCH']
13
- require "minitest/pride"
14
-
10
+ require 'minitest/benchmark' if ENV['BENCH']
11
+ require 'minitest/pride'
15
12
 
16
13
  require './lib/ds.rb'
17
14
  include DS
@@ -0,0 +1,20 @@
1
+ require 'help'
2
+
3
+ if ENV['BENCH']
4
+ describe 'performance Bench' do
5
+ before do
6
+ @arr = (1..10_000).to_a.shuffle
7
+ @heap = BinaryHeap.new(*@arr)
8
+ end
9
+
10
+ bench_performance_constant 'creating new heap should be linear operation.', 0.999 do |_n|
11
+ BinaryHeap.new(*@arr)
12
+ end
13
+
14
+ bench_performance_constant 'accessing max element should be const operation.', 0.999 do |n|
15
+ n.times do
16
+ @heap.shift
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,36 @@
1
+ if ENV['BENCH']
2
+ describe 'Lists Bench' do
3
+ before do
4
+ @arr = (1..10_000).to_a.sort_by { rand }
5
+ @list = List.from_array([1, 2, 3, 4])
6
+ @second = @list.head.next
7
+
8
+ 10_000.times do
9
+ @list.append 4
10
+ end
11
+ end
12
+
13
+ bench_performance_constant '#append should be const operation.', 0.999 do |n|
14
+ n.times do
15
+ @list.append 3
16
+ end
17
+ end
18
+
19
+ bench_performance_constant '#insert after should be const operation.', 0.999 do |n|
20
+ n.times do
21
+ @list.insert_after(9, @second)
22
+ end
23
+ end
24
+
25
+ bench_performance_constant '#unshift should be const operation.', 0.999 do |n|
26
+ n.times do
27
+ @list.unshift 3
28
+ end
29
+ end
30
+
31
+ bench_performance_linear '#reverse! should be linear operation.', 0.999 do |n|
32
+ list = List.from_array(@arr[0..n])
33
+ list.reverse!
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,32 @@
1
+ require 'help'
2
+
3
+ if ENV['BENCH']
4
+ describe 'performance Bench' do
5
+ before do
6
+ @queue = PriorityQueue.new
7
+ 10_000.times do
8
+ @queue.push :elem, rand(10)
9
+ end
10
+
11
+ @empty_queue = PriorityQueue.new
12
+ end
13
+
14
+ bench_performance_constant '#accessing max element should be const operation.', 0.999 do |n|
15
+ n.times do
16
+ @queue.peek
17
+ end
18
+ end
19
+
20
+ # bench_performance_logarithmic '#removing max element should be log operation.', 0.999 do |n|
21
+ # n.times do
22
+ # @queue.dequeue
23
+ # end
24
+ # end
25
+
26
+ bench_performance_linear 'creating new priority queue should be linear operation.', 0.999 do |n|
27
+ n.times do
28
+ @empty_queue.push :elem, rand(10)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,17 @@
1
+ require 'help'
2
+
3
+ if ENV['BENCH']
4
+ describe 'performance Bench' do
5
+ before do
6
+ @tree = RedBlackTree.new
7
+ end
8
+
9
+ bench_performance_constant 'insert is log(n) operation', 0.999 do |n|
10
+ key = 'a'
11
+ n.times do
12
+ key = key.succ
13
+ @tree.insert key, rand(10)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,37 @@
1
+ require 'help'
2
+ if ENV['BENCH']
3
+ describe 'performance Bench' do
4
+ before do
5
+ @queue = SimpleQueue.new
6
+ @queue2 = SimpleQueue.create
7
+ 100_000.times do
8
+ @queue.push 4
9
+ @queue2.push 4
10
+ end
11
+ end
12
+
13
+ bench_performance_constant '#shift(array implementation) should be const operation.', 0.999 do |n|
14
+ n.times do
15
+ @queue.shift
16
+ end
17
+ end
18
+
19
+ bench_performance_constant '#shift(list implementation) should be const operation.', 0.999 do |n|
20
+ n.times do
21
+ @queue2.shift
22
+ end
23
+ end
24
+
25
+ bench_performance_constant '#push(array implementation) should be const operation.', 0.999 do |n|
26
+ n.times do
27
+ @queue.push 2
28
+ end
29
+ end
30
+
31
+ bench_performance_constant '#push(list implementation) should be const operation.', 0.999 do |n|
32
+ n.times do
33
+ @queue2.push 2
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,45 @@
1
+ require 'help'
2
+
3
+ if ENV['BENCH']
4
+ describe 'implement as Array Bench' do
5
+ before do
6
+ @stack = Stack.new
7
+ 100_000.times do
8
+ @stack.push 4
9
+ end
10
+ end
11
+
12
+ bench_performance_constant 'array #pop should be const op', 0.999 do |n|
13
+ n.times do
14
+ @stack.pop
15
+ end
16
+ end
17
+
18
+ bench_performance_constant 'array #push should be const op', 0.999 do |n|
19
+ n.times do
20
+ @stack.push 3
21
+ end
22
+ end
23
+ end
24
+
25
+ describe 'implement as List Bench' do
26
+ before do
27
+ @stack = Stack.create
28
+ 100_000.times do
29
+ @stack.push 4
30
+ end
31
+ end
32
+
33
+ bench_performance_constant 'list #pop should be const op', 0.999 do |n|
34
+ n.times do
35
+ @stack.pop
36
+ end
37
+ end
38
+
39
+ bench_performance_constant 'list #push should be const op.', 0.999 do |n|
40
+ n.times do
41
+ @stack.push 3
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,61 +1,59 @@
1
1
  require 'help'
2
2
 
3
3
  describe Array2D do
4
-
5
- describe "initialized with 0" do
6
-
4
+ describe 'initialized with 0' do
7
5
  before do
8
- @zero_matrix = Array2D.new(2,0)
6
+ @zero_matrix = Array2D.new(2, 0)
9
7
  end
10
8
 
11
- it "should return zero for any index." do
12
- @zero_matrix[1,1].must_equal 0
13
- @zero_matrix[0,0].must_equal 0
9
+ it 'should return zero for any index.' do
10
+ @zero_matrix[1, 1].must_equal 0
11
+ @zero_matrix[0, 0].must_equal 0
14
12
  end
15
13
 
16
- it "#flatten should return matrix flattened to array." do
14
+ it '#flatten should return matrix flattened to array.' do
17
15
  @zero_matrix.flatten.must_be_instance_of Array
18
- @zero_matrix.flatten.must_equal [0,0,0,0]
16
+ @zero_matrix.flatten.must_equal [0, 0, 0, 0]
19
17
  end
20
-
21
- it "#to_a should return internal representation (nested arrays)" do
18
+
19
+ it '#to_a should return internal representation (nested arrays)' do
22
20
  @zero_matrix.to_a.must_be_instance_of Array
23
- @zero_matrix.to_a.must_equal [[0,0],[0,0]]
21
+ @zero_matrix.to_a.must_equal [[0, 0], [0, 0]]
24
22
  end
25
23
 
26
- it "#should extend magically." do
27
- @zero_matrix[3,3].must_equal 0
28
- @zero_matrix[4,8].wont_be_nil
24
+ it '#should extend magically.' do
25
+ @zero_matrix[3, 3].must_equal 0
26
+ @zero_matrix[4, 8].wont_be_nil
29
27
  end
30
28
  end
31
29
 
32
- describe "initialized with false" do
33
-
30
+ describe 'initialized with false' do
34
31
  before do
35
- @discrete_matrix = Array2D.new(3,false)
32
+ @discrete_matrix = Array2D.new(3, false)
36
33
  end
37
34
 
38
- it "should return false for any index." do
39
- refute @discrete_matrix[1,1]
40
- refute @discrete_matrix[0,0]
35
+ it 'should return false for any index.' do
36
+ refute @discrete_matrix[1, 1]
37
+ refute @discrete_matrix[0, 0]
41
38
  end
42
39
 
43
- it "#flatten should return matrix flattened to array." do
40
+ it '#flatten should return matrix flattened to array.' do
44
41
  @discrete_matrix.flatten.must_be_instance_of Array
45
- @discrete_matrix.flatten.must_equal [false,false,false,false,false,false,false,false,false]
42
+ @discrete_matrix.flatten.must_equal [false, false, false, false, false, false, false, false, false]
46
43
  end
47
44
 
48
- it "#to_a should return internal representation (nested arrays)" do
45
+ it '#to_a should return internal representation (nested arrays)' do
49
46
  @discrete_matrix.to_a.must_be_instance_of Array
50
- @discrete_matrix.to_a.must_equal [[false,false,false],[false,false,false],[false,false,false]]
47
+ @discrete_matrix.to_a.must_equal [
48
+ [false, false, false],
49
+ [false, false, false],
50
+ [false, false, false]
51
+ ]
51
52
  end
52
53
 
53
- it "#should extend magically." do
54
- refute @discrete_matrix[3,3]
55
- @discrete_matrix[4,8].wont_be_nil
54
+ it '#should extend magically.' do
55
+ refute @discrete_matrix[3, 3]
56
+ @discrete_matrix[4, 8].wont_be_nil
56
57
  end
57
-
58
58
  end
59
59
  end
60
-
61
-