compsci 0.3.0.1 → 0.3.1.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 +5 -5
- data/README.md +137 -78
- data/Rakefile +3 -1
- data/VERSION +1 -1
- data/compsci.gemspec +2 -2
- data/examples/binary_search_tree.rb +43 -8
- data/examples/complete_tree.rb +21 -22
- data/examples/flex_node.rb +117 -0
- data/examples/heap.rb +40 -2
- data/examples/heap_push.rb +7 -1
- data/examples/ternary_search_tree.rb +30 -0
- data/examples/tree.rb +27 -25
- data/lib/compsci.rb +10 -1
- data/lib/compsci/complete_tree.rb +6 -7
- data/lib/compsci/flex_node.rb +90 -0
- data/lib/compsci/heap.rb +1 -2
- data/lib/compsci/names/pokemon.rb +62 -0
- data/lib/compsci/node.rb +109 -59
- data/lib/compsci/simplex.rb +2 -4
- data/lib/compsci/simplex/parse.rb +4 -4
- data/test/bench/fibonacci.rb +29 -128
- data/test/bench/flex_node.rb +30 -0
- data/test/complete_tree.rb +16 -14
- data/test/compsci.rb +25 -0
- data/test/fibonacci.rb +6 -5
- data/test/fit.rb +30 -26
- data/test/flex_node.rb +226 -0
- data/test/heap.rb +46 -46
- data/test/names.rb +95 -56
- data/test/node.rb +177 -85
- data/test/simplex_parse.rb +23 -15
- data/test/timer.rb +10 -10
- metadata +16 -16
- data/examples/tree_push.rb +0 -72
- data/lib/compsci/binary_search_tree.rb +0 -86
- data/lib/compsci/tree.rb +0 -142
- data/test/bench/tree.rb +0 -31
- data/test/binary_search_tree.rb +0 -98
- data/test/tree.rb +0 -200
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b1ad9a59954ea3377e0e03992dd660fabaf7c65389d633f1e607d3a5b6731ebd
|
4
|
+
data.tar.gz: 5b893649cae5840c590bf4998429087cf50ad9dc97169a2c3ee1566c86748196
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 64100e3719380956c844e7f9eb3949eae097a6d9426b039d0d224260d4bd18a1e1dd7ad7f147643203e21b3ba95d0109bed198d8e5421c9e3c6c21312665b426
|
7
|
+
data.tar.gz: c8944161d1ee4b4df7afac5d27bc0801b2953893ea45db03c30ec1e9f5ee74764638464ee1c3d4d3707107370dd547eedb1f62d09cfe9f20f2efb399e462258f
|
data/README.md
CHANGED
@@ -1,88 +1,107 @@
|
|
1
1
|
[](https://travis-ci.org/rickhull/compsci)
|
2
|
+
[](https://badge.fury.io/rb/compsci)
|
3
|
+
[](https://gemnasium.com/rickhull/compsci)
|
4
|
+
[](https://hakiri.io/github/rickhull/compsci/master)
|
2
5
|
|
3
6
|
# CompSci
|
4
7
|
|
5
8
|
Provided are some toy implementations for some basic computer science problems.
|
6
9
|
|
7
|
-
## [`Node`](lib/compsci/node.rb)
|
10
|
+
## [`Node`](lib/compsci/node.rb) classes
|
11
|
+
|
12
|
+
### `Node`
|
13
|
+
|
14
|
+
A *Node* provides a tree structure by assigning other *Nodes* to `@children`.
|
8
15
|
|
9
16
|
* `Node`
|
10
17
|
- `@value`
|
11
18
|
- `@children`
|
12
|
-
- `#
|
13
|
-
|
14
|
-
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
19
|
+
- `#[]` - child node at index
|
20
|
+
- `#[]=` - set child node at index
|
21
|
+
- `display` - display full tree with all descendents
|
22
|
+
|
23
|
+
* [examples/tree.rb](examples/tree.rb)
|
24
|
+
* [test/node.rb](test/node.rb#L7)
|
25
|
+
|
26
|
+
### `KeyNode`
|
27
|
+
|
28
|
+
A *KeyNode* adds `@key` and allows a comparison based search on the key.
|
29
|
+
[Binary search trees](https://en.wikipedia.org/wiki/Binary_search_tree)
|
30
|
+
are supported, and the `@duplicated` flag determines whether duplicate keys
|
31
|
+
are allowed to be inserted. Any duplicates will not be returned from
|
32
|
+
`#search`. A Ternary search tree is also supported, and it inherently allows
|
33
|
+
duplicates keys. `#search` returns an array of `KeyNode`, possibly empty.
|
34
|
+
|
35
|
+
* `KeyNode < Node`
|
36
|
+
- `KeyNode.key_cmp_idx` - compare 2 keys to decide on a child slot
|
37
|
+
- `@key` - any *Comparable*
|
38
|
+
- `@duplicates` - boolean flag relevant for @children.size == 2
|
39
|
+
- `#cidx` - calls `KeyNode.key_cmp_idx`
|
40
|
+
- `#insert`
|
41
|
+
- `#search`
|
42
|
+
|
43
|
+
* [examples/binary_search_tree.rb](examples/binary_search_tree.rb)
|
44
|
+
* [examples/ternary_search_tree.rb](examples/ternary_search_tree.rb)
|
45
|
+
* [test/node.rb](test/node.rb#L43)
|
46
|
+
|
47
|
+
### `ChildNode`
|
48
|
+
|
49
|
+
A *ChildNode* adds reference to its `@parent`.
|
50
|
+
|
51
|
+
* `ChildNode < Node`
|
20
52
|
- `@parent`
|
21
53
|
- `#gen`
|
22
54
|
- `#siblings`
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
-
|
33
|
-
-
|
34
|
-
|
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`
|
55
|
+
|
56
|
+
* [test/node.rb](test/node.rb#L190)
|
57
|
+
|
58
|
+
## [`CompleteTree`](lib/compsci/complete_tree.rb) classes
|
59
|
+
|
60
|
+
Efficient *Array* implementation of a complete tree uses arithmetic to
|
61
|
+
determine parent/child relationships.
|
62
|
+
|
63
|
+
* `CompleteTree`
|
64
|
+
- `CompleteTree.parent_idx`
|
65
|
+
- `CompleteTree.children_idx`
|
66
|
+
- `CompleteTree.gen`
|
55
67
|
- `@array`
|
56
68
|
- `@child_slots`
|
57
69
|
- `#push`
|
58
70
|
- `#pop`
|
59
71
|
- `#size`
|
60
72
|
- `#last_idx`
|
61
|
-
- `#display`
|
62
|
-
* `CompleteBinaryTree`
|
63
|
-
-
|
64
|
-
* `CompleteTernaryTree`
|
65
|
-
-
|
66
|
-
* `CompleteQuaternaryTree`
|
67
|
-
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
73
|
+
- `#display` - alias `#to_s`
|
74
|
+
* `CompleteBinaryTree < CompleteTree`
|
75
|
+
- `@child_slots = 2`
|
76
|
+
* `CompleteTernaryTree < CompleteTree`
|
77
|
+
- `@child_slots = 3`
|
78
|
+
* `CompleteQuaternaryTree < CompleteTree`
|
79
|
+
- `@child_slots = 4`
|
80
|
+
|
81
|
+
* [examples/complete_tree.rb](examples/complete_tree.rb)
|
82
|
+
* [test/complete_tree.rb](test/complete_tree.rb)
|
83
|
+
* [test/bench/complete_tree.rb](test/bench/complete_tree.rb)
|
84
|
+
|
85
|
+
## [`Heap`](lib/compsci/heap.rb) class
|
86
|
+
|
87
|
+
*CompleteTree* implementation. Both *minheaps* and *maxheaps* are
|
88
|
+
supported. Any number of children may be provided via `child_slots`.
|
89
|
+
The primary operations are `Heap#push` and `Heap#pop`. My basic Vagrant VM
|
90
|
+
gets over [500k pushes per second](reports/examples#L533), constant up past
|
91
|
+
1M pushes.
|
92
|
+
|
93
|
+
* `Heap < CompleteTree`
|
94
|
+
- `#push`
|
95
|
+
- `#pop`
|
96
|
+
- `#sift_up`
|
97
|
+
- `#sift_down`
|
81
98
|
|
82
|
-
|
83
|
-
|
99
|
+
* [examples/heap.rb](examples/heap.rb)
|
100
|
+
* [examples/heap_push.rb](examples/heap_push.rb)
|
101
|
+
* [test/heap.rb](test/heap.rb)
|
102
|
+
* [test/bench/heap.rb](test/bench/heap.rb)
|
84
103
|
|
85
|
-
## [`Fibonacci`](lib/compsci/fibonacci.rb)
|
104
|
+
## [`Fibonacci`](lib/compsci/fibonacci.rb) module
|
86
105
|
|
87
106
|
* `Fibonacci.classic(n)` - naive, recursive
|
88
107
|
* `Fibonacci.cache_recursive(n)` - as above, caching already computed results
|
@@ -90,13 +109,22 @@ pushes](reports/examples#L484).
|
|
90
109
|
* `Fibonacci.dynamic(n)` - as above but without a cache structure
|
91
110
|
* `Fibonacci.matrix(n)` - matrix is magic; beats dynamic around n=500
|
92
111
|
|
93
|
-
|
112
|
+
* [test/fibonacci.rb](test/fibonacci.rb)
|
113
|
+
* [test/bench/fibonacci.rb](test/bench/fibonacci.rb)
|
114
|
+
|
115
|
+
## [`Timer`](/lib/compsci/timer.rb) module
|
94
116
|
|
95
117
|
* `Timer.now` - uses `Process::CLOCK_MONOTONIC` if available
|
96
118
|
* `Timer.since` - provides the elapsed time since a prior time
|
97
119
|
* `Timer.elapsed` - provides the elapsed time to run a block
|
98
120
|
* `Timer.loop_avg` - loops a block; returns final value and mean elapsed time
|
99
121
|
|
122
|
+
* [examples/heap_push.rb](examples/heap_push.rb)
|
123
|
+
* [test/timer.rb](test/timer.rb)
|
124
|
+
* [test/bench/complete_tree.rb](test/bench/complete_tree.rb)
|
125
|
+
* [test/bench/simplex.rb](test/bench/simplex.rb)
|
126
|
+
* [test/timer.rb](test/timer.rb)
|
127
|
+
|
100
128
|
```ruby
|
101
129
|
require 'compsci/timer'
|
102
130
|
|
@@ -142,36 +170,67 @@ elapsed: 0.304
|
|
142
170
|
cumulative: 0.828
|
143
171
|
```
|
144
172
|
|
145
|
-
## [`Fit`](lib/compsci/fit.rb)
|
173
|
+
## [`Fit`](lib/compsci/fit.rb) module
|
146
174
|
|
147
175
|
* `Fit.sigma` - sums the result of a block applied to array values
|
148
176
|
* `Fit.error` - returns a generic r^2 value, the coefficient of determination
|
149
|
-
* `Fit.constant`
|
177
|
+
* `Fit.constant` - fits `y = a + 0x`; returns the mean and variance
|
150
178
|
* `Fit.logarithmic` - fits `y = a + b*ln(x)`; returns a, b, r^2
|
151
|
-
* `Fit.linear`
|
152
|
-
* `Fit.exponential` fits `y = ae^(bx)`; returns a, b, r^2
|
153
|
-
* `Fit.power` fits `y = ax^b`; returns a, b, r^2
|
179
|
+
* `Fit.linear` - fits `y = a + bx`; returns a, b, r^2
|
180
|
+
* `Fit.exponential` - fits `y = ae^(bx)`; returns a, b, r^2
|
181
|
+
* `Fit.power` - fits `y = ax^b`; returns a, b, r^2
|
182
|
+
* `Fit.best` - applies known fits; returns the fit with highest r^2
|
183
|
+
|
184
|
+
* [test/bench/complete_tree.rb](test/bench/complete_tree.rb)
|
185
|
+
* [test/fit.rb](test/fit.rb)
|
186
|
+
|
187
|
+
## [`Names`](lib/compsci/names.rb) module
|
154
188
|
|
155
|
-
|
189
|
+
This helps map a range of small integers to friendly names, typically in
|
190
|
+
alphabetical order.
|
156
191
|
|
192
|
+
* `ENGLISH_UPPER` `ENGLISH_LOWER` `WW1` `WW2` `NATO` `CRYPTO` `PLANETS` `SOLAR`
|
157
193
|
* `Names.assign`
|
158
|
-
|
159
|
-
*
|
160
|
-
*
|
194
|
+
|
195
|
+
* [examples/binary_search_tree.rb](examples/binary_search_tree.rb)
|
196
|
+
* [examples/ternary_search_tree.rb](examples/ternary_search_tree.rb)
|
197
|
+
* [test/names.rb](test/names.rb)
|
198
|
+
* [test/node.rb](test/node.rb)
|
199
|
+
|
200
|
+
### [`Names::Greek`](lib/compsci/names/greek.rb) module
|
201
|
+
|
202
|
+
- `UPPER` `LOWER` `SYMBOLS` `CHAR_MAP` `LATIN_SYMBOLS` `SYMBOLS26`
|
203
|
+
- `Names::Greek.upper`
|
204
|
+
- `Names::Greek.lower`
|
205
|
+
- `Names::Greek.sym`
|
206
|
+
|
207
|
+
### [`Names::Pokemon`](lib/compsci/names/pokemon.rb) module
|
208
|
+
|
209
|
+
- `Names::Pokemon.array`
|
210
|
+
- `Names::Pokemon.hash`
|
211
|
+
- `Names::Pokemon.grep`
|
212
|
+
- `Names::Pokemon.sample`
|
161
213
|
|
162
214
|
## [`Simplex`](lib/compsci/simplex.rb) class
|
163
215
|
|
164
|
-
The Simplex algorithm
|
165
|
-
|
166
|
-
|
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.
|
221
|
+
|
222
|
+
* [test/bench/simplex.rb](test/bench/simplex.rb)
|
223
|
+
* [test/simplex.rb](test/simplex.rb)
|
167
224
|
|
168
|
-
### [`Simplex::Parse`](lib/compsci/simplex/parse.rb)
|
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/
|
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.
|
1
|
+
0.3.1.1
|
data/compsci.gemspec
CHANGED
@@ -16,8 +16,8 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.files += Dir['examples/**/*.rb']
|
17
17
|
|
18
18
|
s.add_development_dependency "buildar", "~> 3.0"
|
19
|
-
s.add_development_dependency "minitest", "
|
20
|
-
s.add_development_dependency "rake", "
|
19
|
+
s.add_development_dependency "minitest", ">= 5.0"
|
20
|
+
s.add_development_dependency "rake", ">= 12.3.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
|
-
|
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
|
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
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
puts tree
|
48
|
+
(1..30).each { |key|
|
49
|
+
node = root.search(key)
|
50
|
+
puts "found #{node}"
|
51
|
+
}
|
data/examples/complete_tree.rb
CHANGED
@@ -1,47 +1,46 @@
|
|
1
1
|
require 'compsci/complete_tree'
|
2
|
-
require 'compsci/timer'
|
3
2
|
|
4
3
|
include CompSci
|
5
4
|
|
6
|
-
|
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
|
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
|
-
|
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
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
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 "
|
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
|