compsci 0.3.0.1 → 0.3.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 6b9d3fa913e9dc0f7aa9f8711e9aa231c00d1022
4
- data.tar.gz: 8436157b3364c791cee0471ae74ca3817f0f4dde
2
+ SHA256:
3
+ metadata.gz: 5a7f1f7282649dec4f08ef08ce3eb3b5b3b97183137624deaa9f20567650185a
4
+ data.tar.gz: 57081ef332e9adc6d3dbdc06b3ff2c9c76955d26b4fdd90402b7547b5544e0fd
5
5
  SHA512:
6
- metadata.gz: 1670fd7283f147996dea2ed2a7a190797a33a5b22b60e8ccfa98a5dc48d61aa6a43302badbc7776b6b7c5a7171a32923ed2dc95f88c23ca998bd1d023d3f4f72
7
- data.tar.gz: f30dd40fb2e5f9e04db6044d7801f1776fb0e1214fd23c29bfbef028dbcd87cab612e434e4df43da477012975561cb7eeef6dab867a53e479612893c53a9e086
6
+ metadata.gz: cdb60b8e1230cdc175ac43afca1efe51bb163ce71dfb2cdd29ffa8ff8ab586456ec181dd46389d54b768edb360f5f9f56d6729bbd65ee86fcd7fa7acee0f417e
7
+ data.tar.gz: 3f20b69bd337aebc862a7f40e1e1177386979f71065200fa18e4dd69bdefb3a382dd8cbd066903d2ba5793cf5c71acd9cd09b79088c4c15b38982b8196bfb0c2
data/README.md CHANGED
@@ -1,88 +1,105 @@
1
- [![Build Status](https://travis-ci.org/rickhull/compsci.svg?branch=master)](https://travis-ci.org/rickhull/compsci)
1
+ [![CI Status](https://github.com/rickhull/compsci/actions/workflows/ci.yaml/badge.svg)](https://github.com/rickhull/compsci/actions/workflows/ci.yaml)
2
+ [![Gem Version](https://badge.fury.io/rb/compsci.svg)](https://badge.fury.io/rb/compsci)
2
3
 
3
4
  # CompSci
4
5
 
5
6
  Provided are some toy implementations for some basic computer science problems.
6
7
 
7
- ## [`Node`](lib/compsci/node.rb) data structure
8
+ ## [`Node`](lib/compsci/node.rb) classes
9
+
10
+ ### `Node`
11
+
12
+ A *Node* provides a tree structure by assigning other *Nodes* to `@children`.
8
13
 
9
14
  * `Node`
10
15
  - `@value`
11
16
  - `@children`
12
- - `#set_child(idx, node)`
13
- * `KeyNode` inherits from `Node`; adds a key
14
- - `@key`
15
- * `FlexNode` inherits from `Node`; accumulates children
16
- - `#add_child(node)`
17
- - `#new_child(value)`
18
- - `#add_parent(node)`
19
- * `ChildNode` inherits from `Node`; adds a parent
17
+ - `#[]` - child node at index
18
+ - `#[]=` - set child node at index
19
+ - `display` - display full tree with all descendents
20
+
21
+ * [examples/tree.rb](examples/tree.rb)
22
+ * [test/node.rb](test/node.rb#L7)
23
+
24
+ ### `KeyNode`
25
+
26
+ A *KeyNode* adds `@key` and allows a comparison based search on the key.
27
+ [Binary search trees](https://en.wikipedia.org/wiki/Binary_search_tree)
28
+ are supported, and the `@duplicated` flag determines whether duplicate keys
29
+ are allowed to be inserted. Any duplicates will not be returned from
30
+ `#search`. A Ternary search tree is also supported, and it inherently allows
31
+ duplicates keys. `#search` returns an array of `KeyNode`, possibly empty.
32
+
33
+ * `KeyNode < Node`
34
+ - `KeyNode.key_cmp_idx` - compare 2 keys to decide on a child slot
35
+ - `@key` - any *Comparable*
36
+ - `@duplicates` - boolean flag relevant for @children.size == 2
37
+ - `#cidx` - calls `KeyNode.key_cmp_idx`
38
+ - `#insert`
39
+ - `#search`
40
+
41
+ * [examples/binary_search_tree.rb](examples/binary_search_tree.rb)
42
+ * [examples/ternary_search_tree.rb](examples/ternary_search_tree.rb)
43
+ * [test/node.rb](test/node.rb#L43)
44
+
45
+ ### `ChildNode`
46
+
47
+ A *ChildNode* adds reference to its `@parent`.
48
+
49
+ * `ChildNode < Node`
20
50
  - `@parent`
21
51
  - `#gen`
22
52
  - `#siblings`
23
- * `ChildFlexNode` inherits from `ChildNode`; accumulates children
24
- - `#add_child(node)`
25
- - `#new_child(value)`
26
- - `#add_parent(node)`
27
-
28
- ## [`Tree`](lib/compsci/tree.rb) data structures
29
-
30
- * `Tree`
31
- - `@root`
32
- - `#df_search`
33
- - `#bf_search`
34
- * `NaryTree`
35
- - `@child_slots` (number of children per node)
36
- - `#open_parent` O(n) to find a node with open child slots
37
- - `#push` append `#open_parent.children`
38
- - `#display` if initialized with `ChildNode`
39
- * `BinaryTree`
40
- - `NaryTree.new(child_slots: 2)`
41
- - `#display` for `Node` and `ChildNode`
42
- * `TernaryTree`
43
- - `NaryTree.new(child_slots: 3)`
44
- * `QuaternaryTree`
45
- - `NaryTree.new(child_slots: 4)`
46
-
47
- ## [`CompleteNaryTree`](lib/compsci/complete_tree.rb) data structure
48
-
49
- Efficient Array implementation of a complete tree.
50
-
51
- * `CompleteNaryTree`
52
- - `CompleteNaryTree.parent_idx`
53
- - `CompleteNaryTree.children_idx`
54
- - `CompleteNaryTree.gen`
53
+
54
+ * [test/node.rb](test/node.rb#L190)
55
+
56
+ ## [`CompleteTree`](lib/compsci/complete_tree.rb) classes
57
+
58
+ Efficient *Array* implementation of a complete tree uses arithmetic to
59
+ determine parent/child relationships.
60
+
61
+ * `CompleteTree`
62
+ - `CompleteTree.parent_idx`
63
+ - `CompleteTree.children_idx`
64
+ - `CompleteTree.gen`
55
65
  - `@array`
56
66
  - `@child_slots`
57
67
  - `#push`
58
68
  - `#pop`
59
69
  - `#size`
60
70
  - `#last_idx`
61
- - `#display` (alias `#to_s`)
62
- * `CompleteBinaryTree`
63
- - `CompleteNaryTree.new(child_slots: 2)`
64
- * `CompleteTernaryTree`
65
- - `CompleteNaryTree.new(child_slots: 3)`
66
- * `CompleteQuaternaryTree`
67
- - `CompleteNaryTree.new(child_slots: 4)`
68
-
69
- ## [`BinarySearchTree`](lib/compsci/binary_search_tree.rb) data structure
70
-
71
- Based on `BinaryTree` with `KeyNode`s. The position of a node depends on its
72
- key and how the key relates to the existing node keys.
73
-
74
- ## [`Heap`](lib/compsci/heap.rb) data structure
75
-
76
- `CompleteNaryTree` implementation. Both minheaps and maxheaps are supported.
77
- Any number of children may be provided via `child_slots`. The primary
78
- operations are `Heap#push` and `Heap#pop`. See the
79
- [heap](examples/heap.rb) [examples](examples/heap_push.rb)
80
- which can be executed (among other examples) via `rake examples`.
71
+ - `#display` - alias `#to_s`
72
+ * `CompleteBinaryTree < CompleteTree`
73
+ - `@child_slots = 2`
74
+ * `CompleteTernaryTree < CompleteTree`
75
+ - `@child_slots = 3`
76
+ * `CompleteQuaternaryTree < CompleteTree`
77
+ - `@child_slots = 4`
78
+
79
+ * [examples/complete_tree.rb](examples/complete_tree.rb)
80
+ * [test/complete_tree.rb](test/complete_tree.rb)
81
+ * [test/bench/complete_tree.rb](test/bench/complete_tree.rb)
82
+
83
+ ## [`Heap`](lib/compsci/heap.rb) class
84
+
85
+ *CompleteTree* implementation. Both *minheaps* and *maxheaps* are
86
+ supported. Any number of children may be provided via `child_slots`.
87
+ The primary operations are `Heap#push` and `Heap#pop`. My basic Vagrant VM
88
+ gets over [500k pushes per second](reports/examples#L533), constant up past
89
+ 1M pushes.
90
+
91
+ * `Heap < CompleteTree`
92
+ - `#push`
93
+ - `#pop`
94
+ - `#sift_up`
95
+ - `#sift_down`
81
96
 
82
- My basic Vagrant VM gets over [500k pushes per second, constant up past 1M
83
- pushes](reports/examples#L484).
97
+ * [examples/heap.rb](examples/heap.rb)
98
+ * [examples/heap_push.rb](examples/heap_push.rb)
99
+ * [test/heap.rb](test/heap.rb)
100
+ * [test/bench/heap.rb](test/bench/heap.rb)
84
101
 
85
- ## [`Fibonacci`](lib/compsci/fibonacci.rb) functions
102
+ ## [`Fibonacci`](lib/compsci/fibonacci.rb) module
86
103
 
87
104
  * `Fibonacci.classic(n)` - naive, recursive
88
105
  * `Fibonacci.cache_recursive(n)` - as above, caching already computed results
@@ -90,13 +107,22 @@ pushes](reports/examples#L484).
90
107
  * `Fibonacci.dynamic(n)` - as above but without a cache structure
91
108
  * `Fibonacci.matrix(n)` - matrix is magic; beats dynamic around n=500
92
109
 
93
- ## [`Timer`](/lib/compsci/timer.rb) functions
110
+ * [test/fibonacci.rb](test/fibonacci.rb)
111
+ * [test/bench/fibonacci.rb](test/bench/fibonacci.rb)
112
+
113
+ ## [`Timer`](/lib/compsci/timer.rb) module
94
114
 
95
115
  * `Timer.now` - uses `Process::CLOCK_MONOTONIC` if available
96
116
  * `Timer.since` - provides the elapsed time since a prior time
97
117
  * `Timer.elapsed` - provides the elapsed time to run a block
98
118
  * `Timer.loop_avg` - loops a block; returns final value and mean elapsed time
99
119
 
120
+ * [examples/heap_push.rb](examples/heap_push.rb)
121
+ * [test/timer.rb](test/timer.rb)
122
+ * [test/bench/complete_tree.rb](test/bench/complete_tree.rb)
123
+ * [test/bench/simplex.rb](test/bench/simplex.rb)
124
+ * [test/timer.rb](test/timer.rb)
125
+
100
126
  ```ruby
101
127
  require 'compsci/timer'
102
128
 
@@ -142,36 +168,69 @@ elapsed: 0.304
142
168
  cumulative: 0.828
143
169
  ```
144
170
 
145
- ## [`Fit`](lib/compsci/fit.rb) functions
171
+ ## [`Fit`](lib/compsci/fit.rb) module
146
172
 
147
173
  * `Fit.sigma` - sums the result of a block applied to array values
148
174
  * `Fit.error` - returns a generic r^2 value, the coefficient of determination
149
- * `Fit.constant` - fits `y = a + 0x`; returns the mean and variance
175
+ * `Fit.constant` - fits `y = a + 0x`; returns the mean and variance
150
176
  * `Fit.logarithmic` - fits `y = a + b*ln(x)`; returns a, b, r^2
151
- * `Fit.linear` - fits `y = a + bx`; returns a, b, r^2
152
- * `Fit.exponential` fits `y = ae^(bx)`; returns a, b, r^2
153
- * `Fit.power` fits `y = ax^b`; returns a, b, r^2
177
+ * `Fit.linear` - fits `y = a + bx`; returns a, b, r^2
178
+ * `Fit.exponential` - fits `y = ae^(bx)`; returns a, b, r^2
179
+ * `Fit.power` - fits `y = ax^b`; returns a, b, r^2
180
+ * `Fit.best` - applies known fits; returns the fit with highest r^2
181
+
182
+ * [test/bench/complete_tree.rb](test/bench/complete_tree.rb)
183
+ * [test/fit.rb](test/fit.rb)
184
+
185
+ ## [`Names`](lib/compsci/names.rb) module
154
186
 
155
- ## [`Names`](lib/compsci/names.rb) functions
187
+ This helps map a range of small integers to friendly names, typically in
188
+ alphabetical order.
156
189
 
190
+ * `ENGLISH_UPPER` `ENGLISH_LOWER` `WW1` `WW2` `NATO` `CRYPTO` `PLANETS` `SOLAR`
157
191
  * `Names.assign`
158
- * `Names::Greek.upper`
159
- * `Names::Greek.lower`
160
- * `Names::Greek.symbol`
192
+
193
+ * [examples/binary_search_tree.rb](examples/binary_search_tree.rb)
194
+ * [examples/ternary_search_tree.rb](examples/ternary_search_tree.rb)
195
+ * [test/names.rb](test/names.rb)
196
+ * [test/node.rb](test/node.rb)
197
+
198
+ ### [`Names::Greek`](lib/compsci/names/greek.rb) module
199
+
200
+ - `UPPER` `LOWER` `SYMBOLS` `CHAR_MAP` `LATIN_SYMBOLS` `SYMBOLS26`
201
+ - `Names::Greek.upper`
202
+ - `Names::Greek.lower`
203
+ - `Names::Greek.sym`
204
+
205
+ ### [`Names::Pokemon`](lib/compsci/names/pokemon.rb) module
206
+
207
+ - `Names::Pokemon.array`
208
+ - `Names::Pokemon.hash`
209
+ - `Names::Pokemon.grep`
210
+ - `Names::Pokemon.sample`
161
211
 
162
212
  ## [`Simplex`](lib/compsci/simplex.rb) class
163
213
 
164
- The Simplex algorithm is a technique for Linear Programming. Typically the
165
- problem is to maximize some linear expression of variables given some
166
- constraints on those variables given in terms of linear inequalities.
214
+ ### WORK IN PROGRESS; DO NOT USE
215
+
216
+ The [Simplex algorithm](https://en.wikipedia.org/wiki/Simplex_algorithm)
217
+ is a technique for
218
+ [Linear programming](https://en.wikipedia.org/wiki/Linear_programming).
219
+ Typically the problem is to maximize some linear expression of variables
220
+ given some constraints on those variables in terms of linear inequalities.
167
221
 
168
- ### [`Simplex::Parse`](lib/compsci/simplex/parse.rb) functions
222
+ * [test/bench/simplex.rb](test/bench/simplex.rb)
223
+ * [test/simplex.rb](test/simplex.rb)
224
+
225
+ ### [`Simplex::Parse`](lib/compsci/simplex/parse.rb) module
169
226
 
170
227
  * `Parse.tokenize` - convert a string to an array of tokens
171
228
  * `Parse.term` - parse certain tokens into [coefficient, varname]
172
229
  * `Parse.expression` - parse a string representing a sum of terms
173
230
  * `Parse.inequality` - parse a string like "#{expression} <= #{const}"
174
231
 
232
+ * [test/simplex_parse.rb](test/simplex_parse.rb)
233
+
175
234
  With `Simplex::Parse`, one can obtain solutions via:
176
235
 
177
236
  * `Simplex.maximize` - takes an expression to maximize followed by a variable
data/Rakefile CHANGED
@@ -78,7 +78,9 @@ scripts = [
78
78
  "examples/heap.rb",
79
79
  "examples/heap_push.rb",
80
80
  "examples/tree.rb",
81
- "examples/tree_push.rb",
81
+ "examples/flex_node.rb",
82
+ "examples/binary_search_tree.rb",
83
+ "examples/ternary_search_tree.rb",
82
84
  ]
83
85
 
84
86
  desc "Run ruby-prof on examples/"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0.1
1
+ 0.3.2.1
data/compsci.gemspec CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |s|
6
6
  s.homepage = "https://github.com/rickhull/compsci"
7
7
  s.license = "LGPL-3.0"
8
8
 
9
- s.required_ruby_version = "~> 2"
9
+ s.required_ruby_version = "~> 3.0"
10
10
 
11
11
  s.version = File.read(File.join(__dir__, 'VERSION')).chomp
12
12
 
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
17
17
 
18
18
  s.add_development_dependency "buildar", "~> 3.0"
19
19
  s.add_development_dependency "minitest", "~> 5.0"
20
- s.add_development_dependency "rake", "~> 0"
20
+ s.add_development_dependency "rake", "~> 12.3" # CVE-2020-8130
21
21
  s.add_development_dependency "flog", "~> 0"
22
22
  s.add_development_dependency "flay", "~> 0"
23
23
  s.add_development_dependency "roodi", "~> 0"
@@ -1,16 +1,51 @@
1
1
  require 'compsci/node'
2
- require 'compsci/binary_search_tree'
3
2
  require 'compsci/names'
4
3
 
5
4
  include CompSci
6
5
 
7
- RANDMAX = 99
6
+ puts <<EOF
7
+
8
+ #
9
+ # Insert nodes into a BST (random keys, duplicates: true)
10
+ #
11
+
12
+ EOF
13
+
14
+ randmax = 99
8
15
 
9
16
  p vals = Names::WW1.shuffle
10
- p keys = Array.new(vals.size) { rand RANDMAX }
17
+ p keys = Array.new(vals.size) { rand randmax }
18
+
19
+ root = KeyNode.new(vals.shift, key: keys.shift, children: 2, duplicates: true)
20
+ root.insert(keys.shift, vals.shift) until keys.empty?
21
+
22
+ puts root.display
23
+ puts
24
+
25
+ puts <<EOF
26
+
27
+ #
28
+ # Insert 30 nodes into a BST (unique keys, duplicates: false)
29
+ #
30
+
31
+ EOF
32
+
33
+ keys = (1..30).to_a.shuffle
34
+ vals = keys.map { rand 99 }
35
+
36
+ root = KeyNode.new(vals.shift, key: keys.shift, children: 2)
37
+ root.insert(keys.shift, vals.shift) while !keys.empty?
38
+ puts root.display
39
+
40
+ puts <<EOF
41
+
42
+ #
43
+ # Search for 30 different keys
44
+ #
45
+
46
+ EOF
11
47
 
12
- root = BinarySearchTree.new_node(keys.shift, vals.shift)
13
- tree = BinarySearchTree.new(root)
14
- tree[keys.shift] = vals.shift until keys.empty?
15
- # tree.insert(keys.shift, vals.shift) until keys.empty?
16
- puts tree
48
+ (1..30).each { |key|
49
+ node = root.search(key)
50
+ puts "found #{node}"
51
+ }
@@ -1,47 +1,46 @@
1
1
  require 'compsci/complete_tree'
2
- require 'compsci/timer'
3
2
 
4
3
  include CompSci
5
4
 
6
- puts <<EOF
5
+ vals = Array.new(30) { rand 99 }
6
+
7
+ [CompleteBinaryTree,
8
+ CompleteTernaryTree,
9
+ CompleteQuaternaryTree].each { |tree_class|
10
+
11
+ puts <<EOF
12
+
7
13
  #
8
- # Print CompleteBinary-, Ternary-, and QuaternaryTree
14
+ # Print #{tree_class} filled with static vals
9
15
  #
10
16
 
11
17
  EOF
12
18
 
13
- vals = Array.new(30) { rand 99 }
14
-
15
- [CompleteBinaryTree,
16
- CompleteTernaryTree,
17
- CompleteQuaternaryTree,
18
- ].each { |tree_class|
19
- # start with the same vals for each class
20
19
  my_vals = vals.dup
21
- p my_vals
20
+ puts "initial vals: #{my_vals.inspect}"
22
21
  tree = tree_class.new
23
22
  tree.push my_vals.shift until my_vals.empty?
23
+
24
24
  p tree
25
- puts tree.display(width: 80)
26
- puts
27
25
  puts
26
+ puts tree.display(width: 80)
28
27
  puts
29
28
 
30
29
 
31
- # TODO: add CompleteTree#df_search
32
- # tree.df_search { |n|
33
- # puts "visited #{n}"
34
- # false # or n.value > 90
35
- # }
36
- # puts
30
+ puts <<EOF
31
+
32
+ #
33
+ # Push random vals and print again
34
+ #
35
+
36
+ EOF
37
37
 
38
- # push different vals for each class
39
38
  my_vals = Array.new(30) { rand 99 }
40
- puts "push: #{my_vals.inspect}"
39
+ puts "new vals: #{my_vals.inspect}"
41
40
 
42
41
  tree.push my_vals.shift until my_vals.empty?
43
- puts tree.display(width: 80)
44
42
  puts
43
+ puts tree.display(width: 80)
45
44
  puts
46
45
  puts
47
46
  }
@@ -0,0 +1,117 @@
1
+ require 'compsci/flex_node'
2
+ require 'compsci/timer'
3
+
4
+ include CompSci
5
+
6
+ puts <<EOF
7
+
8
+ #
9
+ # Try out Binary, Ternary, and Quaternary FlexNodes
10
+ # Push the same vals to each
11
+ #
12
+
13
+ EOF
14
+
15
+ vals = Array.new(30) { rand 99 }
16
+
17
+ [2, 3, 4].each { |child_slots|
18
+ my_vals = vals.dup
19
+ p my_vals
20
+
21
+ root = ChildFlexNode.new my_vals.shift
22
+ root.push(my_vals.shift, child_slots) until my_vals.empty?
23
+ p root
24
+ puts root.display(width: 80)
25
+ puts
26
+ visited = []
27
+ root.df_search { |n|
28
+ visited << n
29
+ false # or n.value > 90
30
+ }
31
+ puts "df_search visited: %s" % visited.join(' ')
32
+ puts
33
+ puts
34
+
35
+ # push different vals for each class
36
+ my_vals = Array.new(30) { rand 99 }
37
+ puts "push: #{my_vals.inspect}"
38
+ root.push(my_vals.shift, child_slots) until my_vals.empty?
39
+ puts
40
+ puts root.display(width: 80)
41
+ puts
42
+ puts
43
+ }
44
+
45
+ puts <<EOF
46
+
47
+ #
48
+ # 30 ChildFlexNode pushes and df_search
49
+ #
50
+
51
+ EOF
52
+
53
+ vals = Array.new(30) { rand 99 }
54
+ p vals
55
+
56
+ root = ChildFlexNode.new vals.shift
57
+ child_slots = 2
58
+ root.push(vals.shift, child_slots) until vals.empty?
59
+ p root
60
+ puts root.display
61
+ puts
62
+
63
+ root.df_search { |n|
64
+ puts "visited #{n}"
65
+ false # or n.value > 90
66
+ }
67
+ puts
68
+
69
+ vals = Array.new(30) { rand 99 }
70
+ puts "push: #{vals.inspect}"
71
+
72
+ root.push(vals.shift, child_slots) until vals.empty?
73
+ puts root.display
74
+ puts
75
+
76
+
77
+ runtime = (ARGV.shift || "3").to_i
78
+ puts <<EOF
79
+
80
+ #
81
+ # #{runtime} seconds worth of Binary ChildFlexNode pushes
82
+ #
83
+
84
+ EOF
85
+
86
+ count = 0
87
+ start = Timer.now
88
+ start_1k = Timer.now
89
+ root = ChildFlexNode.new(rand 99)
90
+ child_slots = 2
91
+
92
+ loop {
93
+ count += 1
94
+
95
+ if count % 100 == 0
96
+ _ans, push_elapsed = Timer.elapsed {
97
+ root.push(rand(99), child_slots)
98
+ }
99
+ puts "%ith push: %0.8f s" % [count, push_elapsed]
100
+
101
+ if count % 1000 == 0
102
+ push_1k_elapsed = Timer.since start_1k
103
+ puts "-----------"
104
+ puts " 1k push: %0.4f s (%i push / s)" %
105
+ [push_1k_elapsed, 1000.to_f / push_1k_elapsed]
106
+ puts
107
+ start_1k = Timer.now
108
+ end
109
+ else
110
+ root.push(rand(99), child_slots)
111
+ end
112
+
113
+ break if Timer.since(start) > runtime
114
+ }
115
+
116
+ puts "pushed %i items in %0.1f s" % [count, Timer.since(start)]
117
+ puts
data/examples/heap.rb CHANGED
@@ -1,11 +1,11 @@
1
1
  require 'compsci/heap'
2
- require 'compsci/timer'
3
2
 
4
3
  include CompSci
5
4
 
6
5
  puts <<EOF
6
+
7
7
  #
8
- # display the results of TernaryHeap push and pop
8
+ # display the results of ternary Heap push and pop
9
9
  #
10
10
 
11
11
  EOF
@@ -38,3 +38,41 @@ puts "array: #{h.array.inspect}"
38
38
  puts "heap: #{h.heap?}"
39
39
  puts h
40
40
  puts
41
+
42
+
43
+ puts <<EOF
44
+
45
+ #
46
+ # display the results of binary Heap push and pop
47
+ #
48
+
49
+ EOF
50
+
51
+ h = Heap.new(child_slots: 2)
52
+
53
+ puts "push: %s" % Array.new(30) { rand(99).tap { |i| h.push i } }.join(' ')
54
+ puts "array: #{h.array.inspect}"
55
+ puts "heap: #{h.heap?}"
56
+ puts h
57
+ puts
58
+ puts
59
+
60
+ puts "pop: %i" % h.pop
61
+ puts "array: #{h.array.inspect}"
62
+ puts "heap: #{h.heap?}"
63
+ puts h
64
+ puts
65
+ puts
66
+
67
+ puts "pop: %s" % Array.new(9) { h.pop }.join(' ')
68
+ puts "array: #{h.array.inspect}"
69
+ puts "heap: #{h.heap?}"
70
+ puts h
71
+ puts
72
+ puts
73
+
74
+ puts "push: %s" % Array.new(30) { rand(99).tap { |i| h.push i } }.join(' ')
75
+ puts "array: #{h.array.inspect}"
76
+ puts "heap: #{h.heap?}"
77
+ puts h
78
+ puts
@@ -6,12 +6,18 @@ include CompSci
6
6
  runtime = (ARGV.shift || "3").to_i
7
7
 
8
8
  puts <<EOF
9
+
9
10
  #
10
- # 3 seconds worth of pushes
11
+ # #{runtime} seconds worth of Heap pushes
11
12
  #
12
13
 
13
14
  EOF
14
15
 
16
+
17
+ # pregenerate a sequence of random numbers
18
+ # every NUMBERWANGth request, shift the sequence and push a new random
19
+ # this should mitigate random number generation from interfering with timing
20
+ # while also mitigating any chance of cyclic behavior
15
21
  RANDMAX = 1_000
16
22
  NUMBERWANG = 1_000
17
23
  NUMS = (0..(RANDMAX - 1)).to_a.shuffle
@@ -0,0 +1,30 @@
1
+ require 'compsci/node'
2
+ require 'compsci/names'
3
+
4
+ include CompSci
5
+
6
+ randmax = (ARGV.shift || 50).to_i
7
+
8
+ puts <<EOF
9
+
10
+ #
11
+ # Insert #{randmax} nodes into a ternary search tree (random keys)
12
+ #
13
+
14
+ EOF
15
+
16
+ root = KeyNode.new(rand(randmax), key: rand(randmax), children: 3)
17
+ randmax.times { puts root.insert(rand(randmax), rand(randmax)) }
18
+ puts root.display
19
+
20
+ puts <<EOF
21
+
22
+ #
23
+ # Search for #{randmax} keys in order
24
+ #
25
+
26
+ EOF
27
+
28
+ randmax.times { |key|
29
+ puts "search #{key}: #{root.search(key).map { |n| n.value }.join(' ')}"
30
+ }