compsci 0.0.3.1 → 0.1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -13,14 +13,14 @@ describe "BinaryTree#push Benchmark" do
13
13
  end
14
14
 
15
15
  bench_performance_constant "BinaryTree#push (constant)" do |n|
16
- tree = BinaryTree.new(ChildNode, 42)
16
+ tree = NaryTree.new(ChildNode, 42, child_slots: 2)
17
17
  n.times { tree.push rand 99 }
18
18
  end
19
19
 
20
20
  bench_performance_linear "BinaryTree#push (linear)" do |n|
21
21
  skip "this fails with r^2 around 0.91"
22
22
 
23
- tree = BinaryTree.new ChildNode.new 42
23
+ tree = NaryTree.new(ChildNode, 42, child_slots: 2)
24
24
  n.times { tree.push rand 99 }
25
25
  end
26
26
  end
@@ -0,0 +1,131 @@
1
+ require 'compsci/complete_tree'
2
+ require 'minitest/autorun'
3
+
4
+ include CompSci
5
+
6
+ describe CompleteNaryTree do
7
+ it "must calculate a parent index for N=2" do
8
+ valid = {
9
+ 1 => 0,
10
+ 2 => 0,
11
+ 3 => 1,
12
+ 4 => 1,
13
+ 5 => 2,
14
+ 6 => 2,
15
+ 7 => 3,
16
+ 8 => 3,
17
+ 9 => 4,
18
+ 10 => 4,
19
+ }
20
+
21
+ invalid = {
22
+ 0 => -1,
23
+ -1 => -1,
24
+ -2 => -2,
25
+ }
26
+ valid.each { |idx, pidx|
27
+ CompleteNaryTree.parent_idx(idx, 2).must_equal pidx
28
+ }
29
+ invalid.each { |idx, pidx|
30
+ CompleteNaryTree.parent_idx(idx, 2).must_equal pidx
31
+ }
32
+ end
33
+
34
+ it "must calculate children indices for N=2" do
35
+ valid = {
36
+ 0 => [1, 2],
37
+ 1 => [3, 4],
38
+ 2 => [5, 6],
39
+ 3 => [7, 8],
40
+ 4 => [9, 10],
41
+ 5 => [11, 12],
42
+ 6 => [13, 14],
43
+ 7 => [15, 16],
44
+ 8 => [17, 18],
45
+ 9 => [19, 20],
46
+ 10 => [21, 22],
47
+ }
48
+
49
+ invalid = {
50
+ -3 => [-5, -4],
51
+ -2 => [-3, -2],
52
+ -1 => [-1, 0],
53
+ }
54
+
55
+ valid.each { |idx, cidx|
56
+ CompleteNaryTree.children_idx(idx, 2).must_equal cidx
57
+ }
58
+ invalid.each { |idx, cidx|
59
+ CompleteNaryTree.children_idx(idx, 2).must_equal cidx
60
+ }
61
+ end
62
+
63
+ it "must calculate a parent index for N=3" do
64
+ valid = {
65
+ 1 => 0,
66
+ 2 => 0,
67
+ 3 => 0,
68
+ 4 => 1,
69
+ 5 => 1,
70
+ 6 => 1,
71
+ 7 => 2,
72
+ 8 => 2,
73
+ 9 => 2,
74
+ 10 => 3,
75
+ }
76
+
77
+ invalid = {
78
+ 0 => -1,
79
+ -1 => -1,
80
+ -2 => -1,
81
+ }
82
+ valid.each { |idx, pidx|
83
+ CompleteNaryTree.parent_idx(idx, 3).must_equal pidx
84
+ }
85
+ invalid.each { |idx, pidx|
86
+ CompleteNaryTree.parent_idx(idx, 3).must_equal pidx
87
+ }
88
+ end
89
+
90
+ it "must calculate children indices for N=3" do
91
+ valid = {
92
+ 0 => [1, 2, 3],
93
+ 1 => [4, 5, 6],
94
+ 2 => [7, 8, 9],
95
+ 3 => [10, 11, 12],
96
+ }
97
+
98
+ invalid = {
99
+ -3 => [-8, -7, -6],
100
+ -2 => [-5, -4, -3],
101
+ -1 => [-2, -1, 0],
102
+ }
103
+
104
+ valid.each { |idx, cidx|
105
+ CompleteNaryTree.children_idx(idx, 3).must_equal cidx
106
+ }
107
+ invalid.each { |idx, cidx|
108
+ CompleteNaryTree.children_idx(idx, 3).must_equal cidx
109
+ }
110
+ end
111
+
112
+ describe "instance" do
113
+ before do
114
+ @array = (0..99).sort_by { rand }
115
+ @empty = CompleteNaryTree.new(child_slots: 5)
116
+ @nonempty = CompleteQuaternaryTree.new(array: @array)
117
+ end
118
+
119
+ it "must have a size" do
120
+ @empty.size.must_equal 0
121
+ @nonempty.size.must_equal @array.size
122
+ end
123
+
124
+ it "must have a last_idx, nil when empty" do
125
+ @empty.last_idx.nil?.must_equal true
126
+ @nonempty.last_idx.must_equal 99
127
+ end
128
+
129
+ # TODO: push, pop, display
130
+ end
131
+ end
@@ -4,43 +4,130 @@ require 'minitest/autorun'
4
4
  include CompSci
5
5
 
6
6
  describe Heap do
7
- before do
8
- @maxheap = Heap.new
9
- @minheap = Heap.new(minheap: true)
10
- @inserts = (1..10).to_a
11
- @inserts.each { |i|
12
- @maxheap.push i
13
- @minheap.push i
14
- }
7
+ describe "MaxHeap" do
8
+ before do
9
+ @maxheap = Heap.new
10
+ @inserts = Array.new(10) { |i| i + 1 }.each { |i| @maxheap.push i }
11
+ end
12
+
13
+ it "must satisfy the heap property" do
14
+ @maxheap.heap?.must_equal true
15
+ @maxheap.array.wont_equal @inserts
16
+ @maxheap.array.wont_equal @inserts.reverse
17
+ end
18
+
19
+ it "must recognize heap violations" do
20
+ @maxheap.array.unshift 0
21
+ @maxheap.heap?.must_equal false
22
+ @maxheap.array.shift
23
+ @maxheap.heap?.must_equal true
24
+
25
+ @maxheap.array.push 10
26
+ @maxheap.heap?.must_equal false
27
+ @maxheap.sift_up @maxheap.last_idx
28
+ @maxheap.heap?.must_equal true
29
+ end
30
+
31
+ it "must pop" do
32
+ @maxheap.pop.must_equal 10
33
+ @maxheap.peek.wont_equal 10
34
+ @maxheap.heap?.must_equal true
35
+ end
36
+
37
+ it "must heapish?" do
38
+ @maxheap.array[0].must_be :>, @maxheap.array[1]
39
+ @maxheap.heapish?(0, 1).must_equal true
40
+ end
41
+
42
+ it "must heapiest" do
43
+ @maxheap.heapiest([1, 2]).must_equal 1
44
+ @maxheap.heapiest([3, 4]).must_equal 4
45
+ @maxheap.heapiest([5, 6]).must_equal 6
46
+ @maxheap.heapiest([7, 8]).must_equal 8
47
+ end
15
48
  end
16
49
 
17
- it "must satisfy the heap property" do
18
- @maxheap.heap?.must_equal true
19
- @minheap.heap?.must_equal true
20
- @minheap.store.must_equal @inserts
21
- @maxheap.store.wont_equal @inserts
22
- @maxheap.store.wont_equal @inserts.reverse
50
+ describe "MinHeap" do
51
+ before do
52
+ @minheap = Heap.new(minheap: true)
53
+ @inserts = Array.new(10) { |i| i + 1 }.each { |i| @minheap.push i }
54
+ end
55
+
56
+ it "must satisfy the heap property" do
57
+ @minheap.heap?.must_equal true
58
+ @minheap.array.must_equal @inserts
59
+ end
60
+
61
+ it "must recognize heap violations" do
62
+ @minheap.array.unshift 10
63
+ @minheap.heap?.must_equal false
64
+ @minheap.array.shift
65
+ @minheap.heap?.must_equal true
66
+
67
+ @minheap.array.push 0
68
+ @minheap.heap?.must_equal false
69
+ @minheap.sift_up @minheap.last_idx
70
+ @minheap.heap?.must_equal true
71
+ end
72
+
73
+ it "must pop" do
74
+ @minheap.pop.must_equal 1
75
+ @minheap.peek.wont_equal 1
76
+ @minheap.heap?.must_equal true
77
+ end
78
+
79
+ it "must heapish?" do
80
+ @minheap.array[0].must_be :<, @minheap.array[1]
81
+ @minheap.heapish?(0, 1).must_equal true
82
+ end
83
+
84
+ it "must heapiest" do
85
+ @minheap.heapiest([1, 2]).must_equal 1
86
+ @minheap.heapiest([3, 4]).must_equal 3
87
+ @minheap.heapiest([5, 6]).must_equal 5
88
+ @minheap.heapiest([7, 8]).must_equal 7
89
+ end
23
90
  end
24
91
 
25
- it "must recognize heap violations" do
26
- @minheap.store.push 0
27
- @minheap.heap?.must_equal false
28
- @minheap.sift_up @minheap.last_idx
29
- @minheap.heap?.must_equal true
30
-
31
- @minheap.store.unshift 10
32
- @minheap.heap?.must_equal false
33
- @minheap.sift_down 0
34
- @minheap.heap?.must_equal true
35
-
36
- @maxheap.store.push 10
37
- @maxheap.heap?.must_equal false
38
- @maxheap.sift_up @maxheap.last_idx
39
- @maxheap.heap?.must_equal true
40
-
41
- @maxheap.store.unshift 0
42
- @maxheap.heap?.must_equal false
43
- @maxheap.sift_down 0
44
- @maxheap.heap?.must_equal true
92
+ describe "TernaryHeap" do
93
+ before do
94
+ @heap3 = Heap.new(child_slots: 3)
95
+ @inserts = Array.new(10) { |i| i + 1 }.each { |i| @heap3.push i }
96
+ end
97
+
98
+ it "must satisfy the heap property" do
99
+ @heap3.heap?.must_equal true
100
+ @heap3.array.wont_equal @inserts
101
+ @heap3.array.wont_equal @inserts.reverse
102
+ end
103
+
104
+ it "must recognize heap violations" do
105
+ @heap3.array.unshift 0
106
+ @heap3.heap?.must_equal false
107
+ @heap3.array.shift
108
+ @heap3.heap?.must_equal true
109
+
110
+ @heap3.array.push 10
111
+ @heap3.heap?.must_equal false
112
+ @heap3.sift_up @heap3.last_idx
113
+ @heap3.heap?.must_equal true
114
+ end
115
+
116
+ it "must pop" do
117
+ @heap3.pop.must_equal 10
118
+ @heap3.peek.wont_equal 10
119
+ @heap3.heap?.must_equal true
120
+ end
121
+
122
+ it "must heapish?" do
123
+ @heap3.array[0].must_be :>, @heap3.array[1]
124
+ @heap3.heapish?(0, 1).must_equal true
125
+ end
126
+
127
+ it "must heapiest" do
128
+ @heap3.heapiest([1, 2, 3]).must_equal 2
129
+ @heap3.heapiest([4, 5, 6]).must_equal 6
130
+ @heap3.heapiest([7, 8, 9]).must_equal 9
131
+ end
45
132
  end
46
133
  end
@@ -0,0 +1,96 @@
1
+ require 'compsci/names'
2
+ require 'minitest/autorun'
3
+
4
+ include CompSci
5
+
6
+ describe Names do
7
+ describe "alphabetic constants" do
8
+ it "must have size 26" do
9
+ Names::WW1.size.must_equal 26
10
+ Names::WW2.size.must_equal 26
11
+ Names::NATO.size.must_equal 26
12
+ Names::ENGLISH_UPPER.size.must_equal 26
13
+ Names::ENGLISH_LOWER.size.must_equal 26
14
+ end
15
+ end
16
+
17
+ describe "Names.assign" do
18
+ it "must handle English / ASCII strings" do
19
+ upper_lower = Names::ENGLISH_UPPER + Names::ENGLISH_LOWER
20
+ Names.assign('cat', Names::ENGLISH_UPPER).must_equal 'C'
21
+ Names.assign('Cat', Names::ENGLISH_UPPER).must_equal 'C'
22
+ Names.assign('cat', Names::ENGLISH_LOWER).must_equal 'c'
23
+ Names.assign('Cat', Names::ENGLISH_LOWER).must_equal 'c'
24
+ Names.assign('Cat', upper_lower).must_equal 'C'
25
+ Names.assign('cat', upper_lower).must_equal 'c'
26
+ Names.assign('cat', Names::NATO).must_equal :charlie
27
+ Names.assign('Cat', Names::NATO).must_equal :charlie
28
+ Names.assign('Dog', Names::CRYPTO).must_equal :david
29
+ Names.assign('2', Names::PLANETS).must_equal :earth
30
+ end
31
+
32
+ it "must handle integers" do
33
+ upper_lower = Names::ENGLISH_UPPER + Names::ENGLISH_LOWER
34
+ Names.assign(36, upper_lower).must_equal 'k'
35
+ Names.assign(0, upper_lower).must_equal 'A'
36
+ Names.assign(0, Names::ENGLISH_UPPER).must_equal 'A'
37
+ Names.assign(3, Names::ENGLISH_LOWER).must_equal 'd'
38
+ Names.assign(3, Names::PLANETS).must_equal :mars
39
+ end
40
+ end
41
+
42
+ describe Names::Greek do
43
+ describe "greek alphabetic constants" do
44
+ it "must have size 24" do
45
+ Names::Greek::UPPER.size.must_equal 24
46
+ Names::Greek::LOWER.size.must_equal 24
47
+ Names::Greek::SYMBOLS.size.must_equal 24
48
+ Names::Greek::CHAR_MAP.size.must_equal 24
49
+ end
50
+ end
51
+
52
+ describe "SYMBOLS26" do
53
+ it "must work well with Names.assign" do
54
+ s26 = Names::Greek::SYMBOLS26
55
+ Names.assign('iota', s26).must_equal :iota
56
+ Names.assign('jota', s26).must_equal :xi
57
+ Names.assign('Query', s26).must_equal :xi
58
+ Names.assign('who', s26).must_equal :xi
59
+ Names.assign('zeta', s26).must_equal :omega
60
+ Names.assign(0, s26).must_equal :alpha
61
+ Names.assign('1', s26).must_equal :beta
62
+ end
63
+ end
64
+ end
65
+
66
+ describe "Greek.sym" do
67
+ it "must handle strings and integers" do
68
+ Names::Greek.sym('cat').must_equal :gamma
69
+ Names::Greek.sym('Cat').must_equal :gamma
70
+ Names::Greek.sym('zeta').must_equal :omega
71
+ Names::Greek.sym(0).must_equal :alpha
72
+ Names::Greek.sym('1').must_equal :beta
73
+ Names::Greek.sym(23).must_equal :omega
74
+ end
75
+ end
76
+
77
+ describe "Greek.lower" do
78
+ it "must handle strings and integers" do
79
+ third = Names::Greek::LOWER[2]
80
+ Names::Greek.lower('cat').must_equal third
81
+ Names::Greek.lower('Cat').must_equal third
82
+ Names::Greek.lower(2).must_equal third
83
+ Names::Greek.lower('2').must_equal third
84
+ end
85
+ end
86
+
87
+ describe "Greek.upper" do
88
+ it "must handle strings and integers" do
89
+ fourth = Names::Greek::UPPER[3]
90
+ Names::Greek.upper('dog').must_equal fourth
91
+ Names::Greek.upper('Dog').must_equal fourth
92
+ Names::Greek.upper(3).must_equal fourth
93
+ Names::Greek.upper('3').must_equal fourth
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,89 @@
1
+ require 'compsci/node'
2
+ require 'minitest/autorun'
3
+
4
+ include CompSci
5
+
6
+ describe Node do
7
+ before do
8
+ @martin_sheen = Node.new 'martin'
9
+ @charlie_sheen = Node.new 'charlie'
10
+ @emilio_estevez = Node.new 'emilio'
11
+ end
12
+
13
+ it "must start with no children" do
14
+ [@martin_sheen, @charlie_sheen, @emilio_estevez].each { |n|
15
+ n.children.must_be_empty
16
+ }
17
+ end
18
+
19
+ it "must track children" do
20
+ @charlie_sheen.add_parent(@martin_sheen)
21
+ @martin_sheen.children.must_include @charlie_sheen
22
+
23
+ @martin_sheen.children.wont_include @emilio_estevez
24
+ @martin_sheen.add_child @emilio_estevez
25
+ @martin_sheen.children.must_include @emilio_estevez
26
+ end
27
+
28
+ it "must not respond to :parent" do
29
+ @martin_sheen.respond_to?(:parent).must_equal false
30
+ end
31
+
32
+ it "must create children from scalars" do
33
+ @martin_sheen.new_child 'fake_emilio'
34
+ @martin_sheen.children.size.must_equal 1
35
+ @martin_sheen.children.first.value.must_equal 'fake_emilio'
36
+ @martin_sheen.children.wont_include @emilio_estevez
37
+ end
38
+ end
39
+
40
+ describe ChildNode do
41
+ before do
42
+ @martin_sheen = ChildNode.new 'martin'
43
+ @charlie_sheen = ChildNode.new 'charlie'
44
+ @emilio_estevez = ChildNode.new 'emilio'
45
+ end
46
+
47
+ it "must start with neither parent nor children" do
48
+ [@martin_sheen, @charlie_sheen, @emilio_estevez].each { |n|
49
+ n.parent.nil?.must_equal true
50
+ n.children.must_be_empty
51
+ }
52
+ end
53
+
54
+ it "must track parent and children" do
55
+ @charlie_sheen.add_parent(@martin_sheen)
56
+ @charlie_sheen.parent.must_equal @martin_sheen
57
+ @martin_sheen.children.must_include @charlie_sheen
58
+
59
+ @martin_sheen.children.wont_include @emilio_estevez
60
+ @martin_sheen.add_child @emilio_estevez
61
+ @martin_sheen.children.must_include @emilio_estevez
62
+ @emilio_estevez.parent.must_equal @martin_sheen
63
+ end
64
+
65
+ it "must determine a node's generation" do
66
+ @emilio_estevez.gen.must_equal 0
67
+ @martin_sheen.add_child @emilio_estevez
68
+ @emilio_estevez.gen.must_equal 1
69
+ end
70
+
71
+ it "must create children from scalars" do
72
+ @martin_sheen.new_child 'fake_emilio'
73
+ @martin_sheen.children.size.must_equal 1
74
+ @martin_sheen.children.first.value.must_equal 'fake_emilio'
75
+ @martin_sheen.children.wont_include @emilio_estevez
76
+ end
77
+
78
+ it "must recognize siblings" do
79
+ @charlie_sheen.add_parent @martin_sheen
80
+ @emilio_estevez.add_parent @martin_sheen
81
+ @martin_sheen.new_child 'fake_emilio'
82
+
83
+ @charlie_sheen.siblings.must_include @emilio_estevez
84
+ @charlie_sheen.siblings.wont_include @martin_sheen
85
+ @emilio_estevez.siblings.must_include @charlie_sheen
86
+ @martin_sheen.siblings.must_be_empty
87
+ @emilio_estevez.siblings.find { |n| n.value == 'fake_emilio' }.wont_be_nil
88
+ end
89
+ end