rubylabs 0.9.0 → 0.9.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.
- data/README.rdoc +15 -6
- data/Rakefile +3 -0
- data/VERSION +1 -1
- data/lib/bitlab.rb +593 -328
- data/lib/demos.rb +20 -9
- data/lib/elizalab.rb +660 -507
- data/lib/hashlab.rb +289 -192
- data/lib/introlab.rb +33 -38
- data/lib/iterationlab.rb +117 -61
- data/lib/marslab.rb +608 -475
- data/lib/randomlab.rb +227 -121
- data/lib/recursionlab.rb +197 -140
- data/lib/rubylabs.rb +936 -390
- data/lib/sievelab.rb +32 -24
- data/lib/spherelab.rb +308 -220
- data/lib/tsplab.rb +634 -312
- data/test/bit_test.rb +4 -4
- data/test/tsp_test.rb +18 -0
- metadata +2 -2
data/lib/randomlab.rb
CHANGED
@@ -1,58 +1,104 @@
|
|
1
|
+
module RubyLabs
|
1
2
|
|
2
3
|
=begin rdoc
|
3
4
|
|
4
5
|
== RandomLab
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
7
|
+
The RandomLab module has definitions of classes and methods used in the projects for Chapter 9
|
8
|
+
of <em>Explorations in Computing</em>. The module has methods used in experiments with pseudorandom
|
9
|
+
number generators.
|
9
10
|
|
10
|
-
=begin
|
11
|
-
TODO number line -- mini-histogram, e.g. second tick drawn above first? else explain in lab manual / reference why two values per tickmark
|
12
|
-
TODO another thing for documentation: diff between p.random(x,y) and random(x,y) [latter uses Ruby's PRNG]
|
13
11
|
=end
|
14
|
-
|
15
|
-
module RubyLabs
|
16
|
-
|
12
|
+
|
17
13
|
module RandomLab
|
18
14
|
|
19
15
|
require "permute.rb"
|
20
16
|
|
17
|
+
NumberLine = Struct.new(:line, :npoints, :options)
|
18
|
+
Histogram = Struct.new(:bins, :max, :keys, :counts, :base, :options)
|
19
|
+
DotPlot = Struct.new(:max, :options)
|
20
|
+
|
21
|
+
@@numberLineOptions = {
|
22
|
+
:lineThickness => 3,
|
23
|
+
:lineColor => '#777777',
|
24
|
+
:tickHeight => 20,
|
25
|
+
:tickWidth => 1,
|
26
|
+
:tickColor => '#0000FF',
|
27
|
+
}
|
28
|
+
|
29
|
+
@@histogramOptions = {
|
30
|
+
:binColor => '#000080',
|
31
|
+
:boxIncrement => 8.0,
|
32
|
+
:rescaleTrigger => 50,
|
33
|
+
}
|
34
|
+
|
35
|
+
@@dotPlotOptions = {
|
36
|
+
:dotColor => '#000080',
|
37
|
+
:dotRadius => 1.0,
|
38
|
+
}
|
39
|
+
|
40
|
+
@@drawing = nil
|
41
|
+
@@delay = 0.01
|
42
|
+
|
21
43
|
=begin rdoc
|
22
|
-
Pseudo-random number generator. Constraints on a, c, and m:
|
23
|
-
* c and m must be relatively prime
|
24
|
-
* a-1 divisible by prime factors of m
|
25
|
-
* if m is multiple of 4, a-1 must also be a multiple of 4
|
26
44
|
|
27
|
-
|
28
|
-
|
45
|
+
== PRNG
|
46
|
+
|
47
|
+
A PRNG object is a pseudorandom number generator based on the mixed congruential method.
|
48
|
+
Sequences generated by a PRNG are defined by three constants, named +a+, +c+, and +m+.
|
49
|
+
If <tt>x[i]</tt> is the current item in the sequence, the equation for the next item
|
50
|
+
<tt>x[i+1]</tt> is
|
51
|
+
x[i+1] = (a * x[i] + c) % m
|
52
|
+
|
29
53
|
=end
|
30
54
|
|
31
55
|
class PRNG
|
32
56
|
|
33
57
|
attr_accessor :a, :c, :m, :x
|
34
58
|
|
59
|
+
# Make a new pseudorandom number generator using constants +a+, +c+, and +m+.
|
60
|
+
#
|
61
|
+
# Example -- a random number generator that has the full period of m = 1000 but some
|
62
|
+
# surprising correlations between successive values:
|
63
|
+
# p = PRNG.new(81, 337, 1000)
|
64
|
+
# => #<RandomLab::PRNG a: 81 c: 337 m: 1000>
|
65
|
+
#
|
66
|
+
# Example: a better PRNG, using values suggested in <em>Numerical Recipes</em> (Press, et al):
|
67
|
+
# >> p = PRNG.new(171, 11213, 53125)
|
68
|
+
# => #<RandomLab::PRNG a: 171 c: 11213 m: 53125>
|
69
|
+
|
35
70
|
def initialize(a, c, m)
|
36
71
|
@a = a
|
37
72
|
@c = c
|
38
73
|
@m = m
|
39
74
|
@x = 0
|
40
75
|
end
|
76
|
+
|
77
|
+
# Return the current item in the pseudorandom sequence (the most recently generated random
|
78
|
+
# number).
|
41
79
|
|
42
80
|
def state
|
43
81
|
return @x
|
44
82
|
end
|
83
|
+
|
84
|
+
# Set the state of the pseudorandom sequence to +val+.
|
45
85
|
|
46
86
|
def seed(val)
|
47
87
|
@x = val
|
48
88
|
end
|
49
|
-
|
89
|
+
|
90
|
+
# Get the next pseudorandom number in the sequence defined by this PRNG object.
|
91
|
+
#--
|
50
92
|
# :begin :advance
|
51
93
|
def advance
|
52
94
|
@x = (@x * @a + @c) % @m
|
53
95
|
end
|
54
96
|
# :end :advance
|
55
97
|
|
98
|
+
# Get a random integer between +min+ and +max+ from this PRNG object. Calls
|
99
|
+
# advance the get the next value from the pseudorandom sequence, then maps it
|
100
|
+
# to an integer between +min+ and +max+.
|
101
|
+
#--
|
56
102
|
# :begin :random
|
57
103
|
def random(min, max)
|
58
104
|
return nil if max <= min
|
@@ -61,6 +107,7 @@ module RandomLab
|
|
61
107
|
end
|
62
108
|
# :end :random
|
63
109
|
|
110
|
+
# Create a string that describes the attributes of this PRNG object.
|
64
111
|
def inspect
|
65
112
|
sprintf "#<RandomLab::PRNG a: #{@a} c: #{@c} m: #{@m}>"
|
66
113
|
end
|
@@ -69,7 +116,12 @@ module RandomLab
|
|
69
116
|
|
70
117
|
end # class PRNG
|
71
118
|
|
72
|
-
#
|
119
|
+
# Return an array of +m+ numbers defined by the pseudorandom sequence with
|
120
|
+
# parameters +a+, +c+, and +m+. The first number in the sequence is 0, and
|
121
|
+
# the remaining numbers are defined by the recurrence
|
122
|
+
# x[i+1] = (a * x[i] + c) % m
|
123
|
+
#--
|
124
|
+
# :begin :prng_sequence
|
73
125
|
def prng_sequence(a, c, m)
|
74
126
|
seq = [0]
|
75
127
|
(m-1).times do
|
@@ -77,35 +129,34 @@ module RandomLab
|
|
77
129
|
end
|
78
130
|
return seq
|
79
131
|
end
|
80
|
-
# :end :prng_sequence
|
81
|
-
|
82
|
-
=begin rdoc
|
83
|
-
Make a new deck of cards
|
84
|
-
=end
|
132
|
+
# :end :prng_sequence
|
85
133
|
|
134
|
+
# Make a new deck of cards. Returns an array of 52 card objects, arranged
|
135
|
+
# in order from card #0 (the ace of spades) through card #51 (the two of clubs).
|
136
|
+
|
86
137
|
def new_deck
|
87
138
|
(0..51).map { |i| Card.new(i) }
|
88
139
|
end
|
89
140
|
|
90
141
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
142
|
+
# Compute the probability of a duplicate item in a collection of +n+ items
|
143
|
+
# drawn from the range [1..d].
|
144
|
+
#
|
145
|
+
# Example -- to compute the
|
146
|
+
# probability of drawing the same card twice when sampling with replacement
|
147
|
+
# 5 times from a deck of 52 cards:
|
148
|
+
# >> pdup(5, 52)
|
149
|
+
# => 0.179716221420819
|
97
150
|
|
98
151
|
def pdup(n, d)
|
99
152
|
return 1.0 if n > d
|
100
153
|
return 1.0 - (1..(n-1)).inject(1.0) { |p, k| p * (1.0 - (k / 52.0)) }
|
101
154
|
end
|
102
155
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
# Note: permute! moved to own source file, permute.rb
|
156
|
+
# A helper method intended to be called via a probe to print the contents
|
157
|
+
# of an array during the execution of the <tt>permute!</tt> method. The arguments
|
158
|
+
# are the array to display, the location of a left bracket, and the item
|
159
|
+
# location where the item next to the bracket will be moved on the next swap.
|
109
160
|
|
110
161
|
def brackets(a, i, r)
|
111
162
|
res = "#{r}: "
|
@@ -121,19 +172,17 @@ module RandomLab
|
|
121
172
|
return res
|
122
173
|
end
|
123
174
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
=end
|
136
|
-
|
175
|
+
# Given an array of 5 Card objects, determine what type of poker hand is
|
176
|
+
# represented by the cards. The return value is a symbol, e.g. <tt>:pair</tt>,
|
177
|
+
# <tt>:full_house</tt>, etc. (call poker_rankings to see the complete list of
|
178
|
+
# symbols).
|
179
|
+
#
|
180
|
+
# Example (assuming +d+ is a complete deck of 52 Card objects):
|
181
|
+
# >> h = permute!(d).first(5)
|
182
|
+
# => [AH, 6S, 7C, JH, AC]
|
183
|
+
# >> poker_rank(h)
|
184
|
+
# => :pair
|
185
|
+
|
137
186
|
def poker_rank(a)
|
138
187
|
rcount = Array.new(Card::Ranks.length, 0)
|
139
188
|
scount = Array.new(Card::Suits.length, 0)
|
@@ -158,28 +207,35 @@ module RandomLab
|
|
158
207
|
return :pair
|
159
208
|
end
|
160
209
|
end
|
210
|
+
|
211
|
+
# Return a list of symbols used to classify poker hands.
|
161
212
|
|
162
213
|
def poker_rankings
|
163
214
|
return [:high_card, :pair, :two_pair, :three_of_a_kind, :straight, :flush, :full_house, :four_of_a_kind, :straight_flush]
|
164
215
|
end
|
165
216
|
|
217
|
+
# Initialize a Hash object with keys that are poker rank symbols and values that are all initially 0.
|
218
|
+
# Used in experiments that count the number of times various hands are dealt.
|
219
|
+
#
|
220
|
+
# Example:
|
221
|
+
# >> poker_counts
|
222
|
+
# => {:flush=>0, :full_house=>0, ... :high_card=>0}
|
223
|
+
|
166
224
|
def poker_counts
|
167
225
|
h = Hash.new
|
168
226
|
poker_rankings.each { |x| h[x] = 0 }
|
169
227
|
return h
|
170
228
|
end
|
171
229
|
|
172
|
-
|
173
230
|
=begin rdoc
|
174
|
-
Class to represent cards from a standard 52-card deck. Includes comparators
|
175
|
-
to sort by rank or suit.
|
176
|
-
|
177
|
-
Call Card.new to get a random card, or Card.new(id) to get a specific card
|
178
|
-
where id is a number between 0 and 51.
|
179
|
-
=end
|
180
231
|
|
181
|
-
|
182
|
-
|
232
|
+
== Card
|
233
|
+
|
234
|
+
A Card object represents a single card from a standard 52-card deck. The two
|
235
|
+
attributes of a card are its rank (represented by a symbol such as :ace, :king, :three, etc)
|
236
|
+
and its suit (:spades, :hearts, etc).
|
237
|
+
|
238
|
+
=end
|
183
239
|
|
184
240
|
class Card
|
185
241
|
attr_accessor :rank, :suit
|
@@ -192,16 +248,43 @@ module RandomLab
|
|
192
248
|
Ranks = [:ace, :king, :queen, :jack, :ten, :nine, :eight, :seven, :six, :five, :four, :three, :two]
|
193
249
|
end
|
194
250
|
|
251
|
+
# Create a new Card object. Cards are ordered from 0 to 51, with 0 being the ace of spades
|
252
|
+
# and 51 being the two of clubs. If no argument is passed to new, a random card is chosen.
|
253
|
+
# If an +id+ between 0 and 51 is passed the specified card is created.
|
254
|
+
#
|
255
|
+
# Example:
|
256
|
+
# >> Card.new
|
257
|
+
# => 5H
|
258
|
+
# >> Card.new(0)
|
259
|
+
# => AS
|
260
|
+
# >> Card.new(1)
|
261
|
+
# => KS
|
262
|
+
# >> Card.new(51)
|
263
|
+
# => 2C
|
264
|
+
|
195
265
|
def initialize(id = nil)
|
196
266
|
id = rand(52) if id.nil?
|
197
267
|
raise "card must be between 0 and 51" if id < 0 || id > 51
|
198
268
|
@suit = Suits[id / 13]
|
199
269
|
@rank = Ranks[id % 13]
|
200
270
|
end
|
271
|
+
|
272
|
+
# Compare this Card with Card x. Two cards are equal if they have the same
|
273
|
+
# suit and same rank.
|
201
274
|
|
202
275
|
def ==(x)
|
203
276
|
return @suit == x.suit && @rank == x.rank
|
204
277
|
end
|
278
|
+
|
279
|
+
# Define the sort ordering for Card objects. Cards are compared first by suit,
|
280
|
+
# and then by rank. The result of sorting a hand (and array of Card objects) is
|
281
|
+
# the common situation for most card games, where cards are grouped by suit.
|
282
|
+
#
|
283
|
+
# Example (assuming +d+ is a complete deck of 52 cards):
|
284
|
+
# >> h = permute!(d).first(13)
|
285
|
+
# => [2C, QS, 8S, 6C, 10H, JS, AD, AS, 7D, 8D, JC, 4C, AH]
|
286
|
+
# >> h.sort
|
287
|
+
# => [AS, QS, JS, 8S, AH, 10H, AD, 8D, 7D, JC, 6C, 4C, 2C]
|
205
288
|
|
206
289
|
def <=>(x)
|
207
290
|
r0 = Ranks.index(@rank); r1 = Ranks.index(x.rank)
|
@@ -215,6 +298,11 @@ module RandomLab
|
|
215
298
|
|
216
299
|
@@outputform = :utf8
|
217
300
|
|
301
|
+
# Make a string to display a Card objects on the terminal. Checks
|
302
|
+
# Ruby's $KCODE global variable to see if the system is using UTF-8. If so, the code for a glyph that
|
303
|
+
# shows a spade, heart, diamond, or club is inserted into the string, otherwise a letter is
|
304
|
+
# used.
|
305
|
+
|
218
306
|
def inspect
|
219
307
|
s = ""
|
220
308
|
s << case @rank
|
@@ -252,7 +340,6 @@ module RandomLab
|
|
252
340
|
end
|
253
341
|
end
|
254
342
|
return s
|
255
|
-
# "#{@rank} #{@suit}"
|
256
343
|
end
|
257
344
|
|
258
345
|
alias to_s inspect
|
@@ -267,21 +354,18 @@ module RandomLab
|
|
267
354
|
|
268
355
|
end # class Card
|
269
356
|
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
plot_point(x,y) add a dot at (x,y) to the dotplot
|
283
|
-
=end
|
284
|
-
|
357
|
+
# Initialize the RubyLabs Canvas with a drawing of a number line for integers from 0 to +npoints+-1.
|
358
|
+
# Options that control the appearance of the display, and their default values, are:
|
359
|
+
# :lineThickness => 3
|
360
|
+
# :lineColor => '#777777'
|
361
|
+
# :tickHeight => 20
|
362
|
+
# :tickWidth => 1
|
363
|
+
# :tickColor => '#0000FF'
|
364
|
+
#
|
365
|
+
# Example:
|
366
|
+
# >> view_numberline(500, :lineColor => 'blue', :lineThickness => 1)
|
367
|
+
# => true
|
368
|
+
|
285
369
|
def view_numberline(npoints, userOptions = {})
|
286
370
|
Canvas.init(500, 100, "RandomLab::NumberLine")
|
287
371
|
options = @@numberLineOptions.merge(userOptions)
|
@@ -290,21 +374,48 @@ module RandomLab
|
|
290
374
|
return true
|
291
375
|
end
|
292
376
|
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
377
|
+
# Draw a tick mark on the RubyLabs Canvas, provided the canvas has been initialized with a call to
|
378
|
+
# view_numberline.
|
379
|
+
|
380
|
+
def tick_mark(i)
|
381
|
+
if @@drawing.class != NumberLine
|
382
|
+
puts "call view_numberline to initialize the number line"
|
383
|
+
elsif i < 0 || i >= @@drawing.npoints
|
384
|
+
puts "tick_mark: 0 <= i < #{@@drawing.npoints}"
|
385
|
+
else
|
386
|
+
x0, y0, x1, y1 = @@drawing.line.coords
|
387
|
+
tx = (i.to_f / @@drawing.npoints) * (x1-x0)
|
388
|
+
ty = y0 - @@drawing.options[:tickHeight]
|
389
|
+
Canvas::Line.new(tx, y0, tx, ty, :width => @@drawing.options[:tickWidth], :fill => @@drawing.options[:tickColor])
|
390
|
+
sleep(@@delay)
|
391
|
+
end
|
392
|
+
return true
|
393
|
+
end
|
394
|
+
|
395
|
+
# Initialize the RubyLabs Canvas to show a histogram with the specified bins. In the
|
396
|
+
# initial drawing each bin is represented by a rectangle one pixel tall, i.e. a horizontal line.
|
397
|
+
# As items are added to a bin the rectangle will grow in height. If any rectangle reaches the
|
398
|
+
# maximum height, all the rectangles are rescaled so the bins can continue to grow.
|
399
|
+
#
|
400
|
+
# The argument to view_histogram can either be an integer, which specifies the number of bins,
|
401
|
+
# or an array of symbols, in which case there will be one bin for each symbol. If the argument is an integer,
|
402
|
+
# a second argument can specify a maximum data value; for example, calling <tt>view_histogram(10,100)</tt>
|
403
|
+
# will make a histogram with 10 bins for numbers between 0 and 99, so that data values 0 through
|
404
|
+
# 9 will go in the first bin, 10 through 19 in the second bin, and so on.
|
405
|
+
#
|
406
|
+
# Display options and their default values are:
|
407
|
+
# :binColor => '#000080'
|
408
|
+
# :boxIncrement => 8.0
|
409
|
+
# :rescaleTrigger => 50
|
410
|
+
#
|
411
|
+
# Example: make a histogram for the numbers between 0 and 5:
|
412
|
+
# >> view_histogram(6)
|
413
|
+
# => true
|
414
|
+
# Example: make a histogram to count the number of times each type of poker hand is seen in an
|
415
|
+
# experiment:
|
416
|
+
# >> view_histogram(poker_rankings, :binColor => 'darkgreen')
|
417
|
+
# => true
|
418
|
+
|
308
419
|
def view_histogram(*args)
|
309
420
|
begin
|
310
421
|
if args[0].class == Array
|
@@ -341,7 +452,10 @@ module RandomLab
|
|
341
452
|
|
342
453
|
return true
|
343
454
|
end
|
344
|
-
|
455
|
+
|
456
|
+
# Update the bin for data item +x+, presuming the RubyLabs Canvas has been initialized to show
|
457
|
+
# a histogram for data of this type. The bin for +x+ increases in height. If it reaches
|
458
|
+
# the maximum height, rescale all the bins and increase the maximum height.
|
345
459
|
|
346
460
|
def update_bin(x)
|
347
461
|
if @@drawing.class != Histogram
|
@@ -380,6 +494,8 @@ module RandomLab
|
|
380
494
|
sleep(@@delay)
|
381
495
|
return true
|
382
496
|
end
|
497
|
+
|
498
|
+
# Return an array of counts for the bins in the histogram currently on the RubyLabs Canvas.
|
383
499
|
|
384
500
|
def get_counts
|
385
501
|
if @@drawing.class == Histogram
|
@@ -389,55 +505,45 @@ module RandomLab
|
|
389
505
|
return nil
|
390
506
|
end
|
391
507
|
end
|
392
|
-
|
508
|
+
|
509
|
+
# Initialize the RubyLabs Canvas to show a dot plot with +npoints+ in both the +x+
|
510
|
+
# and +y+ dimension. Drawing options and their defaults are
|
511
|
+
# :dotColor => '#000080'
|
512
|
+
# :dotRadius => 1.0
|
513
|
+
#
|
514
|
+
# Example: intialize the drawing for a 250 x 250 dot plot with green dots:
|
515
|
+
# >> view_dotplot(250, :dotColor => 'darkgreen')
|
516
|
+
# => true
|
517
|
+
|
393
518
|
def view_dotplot(npoints, userOptions = {})
|
394
519
|
Canvas.init(500, 500, "RandomLab::DotPlot")
|
395
520
|
options = @@dotPlotOptions.merge(userOptions)
|
396
521
|
@@drawing = DotPlot.new(npoints, options)
|
397
522
|
return true
|
398
523
|
end
|
524
|
+
|
525
|
+
# Add a point at location 'x', 'y' to the dot plot on the RubyLabs Canvas.
|
526
|
+
#
|
527
|
+
# Example: if the canvas was initialized to show a 250 x 250 plot, this call
|
528
|
+
# will display a point in the center of the drawing:
|
529
|
+
# >> plot_point(125,125)
|
530
|
+
# => nil
|
399
531
|
|
400
532
|
def plot_point(x,y)
|
401
533
|
if @@drawing.class != DotPlot
|
402
534
|
puts "call view_dotplot to initialize a dot plot"
|
403
|
-
|
404
|
-
|
405
|
-
|
535
|
+
elsif x < 0 || x >= @@drawing.max || y < 0 || y >= @@drawing.max
|
536
|
+
puts "plot_point: 0 <= x, y < #{@@drawing.max}"
|
537
|
+
else
|
406
538
|
px = (x.to_f / @@drawing.max) * Canvas.width
|
407
539
|
py = (y.to_f / @@drawing.max) * Canvas.height
|
408
540
|
r = @@drawing.options[:dotRadius]
|
409
541
|
color = @@drawing.options[:dotColor]
|
410
542
|
Canvas::Circle.new( px, py, r, :outline => color, :fill => color )
|
411
|
-
|
412
|
-
|
543
|
+
end
|
544
|
+
return nil
|
413
545
|
end
|
414
|
-
|
415
|
-
NumberLine = Struct.new(:line, :npoints, :options)
|
416
|
-
Histogram = Struct.new(:bins, :max, :keys, :counts, :base, :options)
|
417
|
-
DotPlot = Struct.new(:max, :options)
|
418
|
-
|
419
|
-
@@numberLineOptions = {
|
420
|
-
:lineThickness => 3,
|
421
|
-
:lineColor => '#777777',
|
422
|
-
:tickHeight => 20,
|
423
|
-
:tickWidth => 1,
|
424
|
-
:tickColor => '#0000FF',
|
425
|
-
}
|
426
|
-
|
427
|
-
@@histogramOptions = {
|
428
|
-
:binColor => '#000080',
|
429
|
-
:boxIncrement => 8.0,
|
430
|
-
:rescaleTrigger => 50,
|
431
|
-
}
|
432
|
-
|
433
|
-
@@dotPlotOptions = {
|
434
|
-
:dotColor => '#000080',
|
435
|
-
:dotRadius => 1.0,
|
436
|
-
}
|
437
|
-
|
438
|
-
@@drawing = nil
|
439
|
-
@@delay = 0.01
|
440
|
-
|
546
|
+
|
441
547
|
end # RandomLab
|
442
548
|
|
443
549
|
end # RubyLabs
|