compsci 0.3.0.1 → 0.3.2.1

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.
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
+ }