rubylabs 0.5.4
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/LICENSE +20 -0
- data/README.rdoc +9 -0
- data/Rakefile +63 -0
- data/VERSION +1 -0
- data/bin/bb.rb +12 -0
- data/bin/statistics2-0.53/ext/extconf.rb +11 -0
- data/bin/statistics2-0.53/ext/show.rb +11 -0
- data/bin/statistics2-0.53/ext/t.rb +46 -0
- data/bin/statistics2-0.53/mklist.rb +26 -0
- data/bin/statistics2-0.53/sample-tbl.rb +129 -0
- data/bin/statistics2-0.53/statistics2.rb +532 -0
- data/bin/statistics2-0.53/t-inv.rb +54 -0
- data/bin/statistics2.rb +532 -0
- data/data/aafreq.txt +20 -0
- data/data/cars.txt +50 -0
- data/data/century.txt +1 -0
- data/data/colors.txt +64 -0
- data/data/earth.yaml +15 -0
- data/data/fruit.txt +45 -0
- data/data/hacodes.txt +35 -0
- data/data/hafreq.txt +16 -0
- data/data/hvfreq.txt +5 -0
- data/data/nbody.R +23 -0
- data/data/nbody.out +731 -0
- data/data/nbody.pdf +3111 -0
- data/data/nbody.png +0 -0
- data/data/nbody3d.pdf +3201 -0
- data/data/outer.pdf +182785 -0
- data/data/solar.dat +36501 -0
- data/data/solarsystem.txt +17 -0
- data/data/suits.txt +1 -0
- data/data/wordlist.txt +210653 -0
- data/lib/bitlab.rb +624 -0
- data/lib/elizalab.rb +523 -0
- data/lib/encryptionlab.rb +42 -0
- data/lib/hashlab.rb +224 -0
- data/lib/introlab.rb +14 -0
- data/lib/iterationlab.rb +130 -0
- data/lib/randomlab.rb +294 -0
- data/lib/recursionlab.rb +228 -0
- data/lib/rubylabs.rb +507 -0
- data/lib/sievelab.rb +58 -0
- data/lib/sortlab.rb +213 -0
- data/lib/spherelab.rb +352 -0
- data/lib/temps.rb +41 -0
- data/lib/tsplab.rb +416 -0
- data/lib/viewer.rb +65 -0
- data/test/bit_test.rb +175 -0
- data/test/encryption_test.rb +20 -0
- data/test/iteration_test.rb +40 -0
- data/test/random_test.rb +64 -0
- data/test/recursion_test.rb +47 -0
- data/test/rubylabs_test.rb +18 -0
- data/test/sieve_test.rb +28 -0
- data/test/sphere_test.rb +130 -0
- data/test/temps_test.rb +24 -0
- data/test/test_helper.rb +18 -0
- metadata +112 -0
data/lib/elizalab.rb
ADDED
@@ -0,0 +1,523 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
=begin rdoc
|
4
|
+
|
5
|
+
== ELIZA
|
6
|
+
|
7
|
+
Joseph Weizenbaum's ELIZA program in Ruby. Students can play with the Doctor script,
|
8
|
+
which mimics a Rogerian psychiatrist, and experiment by adding new rules to Doctor or
|
9
|
+
writing their own scripts.
|
10
|
+
|
11
|
+
=end
|
12
|
+
|
13
|
+
require 'priorityqueue'
|
14
|
+
|
15
|
+
require 'readline'
|
16
|
+
include Readline
|
17
|
+
|
18
|
+
|
19
|
+
class String
|
20
|
+
|
21
|
+
=begin rdoc
|
22
|
+
A useful operation on strings -- call +s.unquote+ to remove double quotes from
|
23
|
+
the beginning and end of string +s+.
|
24
|
+
=end
|
25
|
+
|
26
|
+
def unquote
|
27
|
+
if self[0] == ?" && self[-1] == ?"
|
28
|
+
return self.slice(1..-2)
|
29
|
+
else
|
30
|
+
return self
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
=begin rdoc
|
37
|
+
|
38
|
+
A transformation rule is associated with a key word, and is triggered
|
39
|
+
when that word is found in an input sentence. Rules have integer
|
40
|
+
priorities, and if more than one rule is enabled ELIZA applies the one
|
41
|
+
with the highest priority. Each rule has an ordered list of patterns,
|
42
|
+
and each pattern has a list of reassembly rules.
|
43
|
+
|
44
|
+
To apply a rule, scan the patterns, and for the first pattern that matches
|
45
|
+
a sentence, build the output using the current reassembly rule.
|
46
|
+
|
47
|
+
=end
|
48
|
+
|
49
|
+
class Rule
|
50
|
+
|
51
|
+
attr_accessor :key, :priority, :patterns
|
52
|
+
|
53
|
+
=begin rdoc
|
54
|
+
Specify the key word for a rule when the rule is created.
|
55
|
+
=end
|
56
|
+
def initialize(key, priority = 1)
|
57
|
+
@key = key
|
58
|
+
@priority = priority
|
59
|
+
@patterns = Array.new
|
60
|
+
end
|
61
|
+
|
62
|
+
def addPattern(expr)
|
63
|
+
if expr.class == Pattern
|
64
|
+
@patterns << expr
|
65
|
+
else
|
66
|
+
if expr.class == String
|
67
|
+
expr = Regexp.new(expr.slice(1..-2))
|
68
|
+
end
|
69
|
+
@patterns << Pattern.new(expr)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def [](n)
|
74
|
+
@patterns[n]
|
75
|
+
end
|
76
|
+
|
77
|
+
def addReassembly(line, n = -1)
|
78
|
+
@patterns[n].addText(line)
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
=begin rdoc
|
83
|
+
Rule application -- try the patterns in order. When the line matches a pattern,
|
84
|
+
return the next reassembly for that pattern. Apply variable substitutions to both
|
85
|
+
the patterns and the reassemblies if they contain variables.
|
86
|
+
=end
|
87
|
+
|
88
|
+
|
89
|
+
def apply(s, post = {}, verbose = false)
|
90
|
+
@patterns.each do |p|
|
91
|
+
if verbose
|
92
|
+
print "trying pattern "
|
93
|
+
p p.regexp
|
94
|
+
end
|
95
|
+
res = p.apply( s, post, verbose )
|
96
|
+
return res if ! res.nil?
|
97
|
+
end
|
98
|
+
return nil
|
99
|
+
end
|
100
|
+
|
101
|
+
def to_s
|
102
|
+
s = @key + " / " + @priority.to_s + "\n"
|
103
|
+
@patterns.each { |r| s += " " + r.to_s + "\n" }
|
104
|
+
return s
|
105
|
+
end
|
106
|
+
|
107
|
+
def inspect
|
108
|
+
s = @key.inspect
|
109
|
+
s += " [#{@priority}]" if @priority > 1
|
110
|
+
s += " --> [\n" + @patterns.join("\n") + "]"
|
111
|
+
return s
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
=begin rdoc
|
117
|
+
|
118
|
+
A Pattern represents one way to transform an input sentence into a
|
119
|
+
response. A Pattern instance has a regular expression and a list of
|
120
|
+
one or more reassembly strings that can refer to groups in the expression.
|
121
|
+
There is also an index to record the last reassembly string used, so
|
122
|
+
the application can cycle through the strings.
|
123
|
+
|
124
|
+
For convenience the constructor inserts word break anchors and attaches
|
125
|
+
a /i to the expression as needed. NOTE: the inspect method removes these
|
126
|
+
automatic items so the printed string is cleaner; to see the real Regexp
|
127
|
+
call the regexp accessor. Example:
|
128
|
+
|
129
|
+
>> p = Pattern.new(/hi/,"hello")
|
130
|
+
=> /hi/ -> ["hello"] [0]
|
131
|
+
>> p.regexp
|
132
|
+
=> /\bhi\b/i
|
133
|
+
|
134
|
+
=end
|
135
|
+
|
136
|
+
|
137
|
+
class Pattern
|
138
|
+
attr_accessor :regexp, :list, :index
|
139
|
+
|
140
|
+
def initialize(expr, text = nil)
|
141
|
+
re = expr.inspect
|
142
|
+
re.insert(1,'\b') if re =~ /^\/\w/
|
143
|
+
re.insert(-2,'\b') if re =~ /\w\/$/
|
144
|
+
re += "i" unless re =~ /\/i$/
|
145
|
+
@regexp = eval(re)
|
146
|
+
|
147
|
+
if text.nil?
|
148
|
+
@list = Array.new
|
149
|
+
elsif text.class == String
|
150
|
+
@list = [text]
|
151
|
+
elsif text.class == Array
|
152
|
+
@list = text
|
153
|
+
else
|
154
|
+
raise "Pattern.initialize: text argument must be nil, String, or Array"
|
155
|
+
end
|
156
|
+
|
157
|
+
@index = 0
|
158
|
+
end
|
159
|
+
|
160
|
+
def addText(line)
|
161
|
+
@list << line
|
162
|
+
end
|
163
|
+
|
164
|
+
def inc
|
165
|
+
n = @index
|
166
|
+
@index = (@index + 1) % @list.length
|
167
|
+
return n
|
168
|
+
end
|
169
|
+
|
170
|
+
def apply(s, post = {}, verbose = false)
|
171
|
+
md = s.match(@regexp)
|
172
|
+
return nil if @list.empty? || md == nil
|
173
|
+
res = @list[inc()].clone
|
174
|
+
return res if res[0] == ?@
|
175
|
+
puts "reassembling '#{res}'" if verbose
|
176
|
+
res.gsub!(/\$\d+/) do |ns|
|
177
|
+
n = ns.slice(1..-1).to_i # strip leading $, convert to int
|
178
|
+
if n && md[n]
|
179
|
+
puts "postprocess #{md[n]}" if verbose
|
180
|
+
md[n].gsub(/[a-z\-$']+/i) do |w|
|
181
|
+
(post.has_key?(w) && post[w][0] != ?$) ? post[w] : w
|
182
|
+
end
|
183
|
+
else
|
184
|
+
warn "Pattern.apply: bad argument #{ns} in #{res}"
|
185
|
+
""
|
186
|
+
end
|
187
|
+
end
|
188
|
+
return res
|
189
|
+
end
|
190
|
+
|
191
|
+
def cleanRegexp
|
192
|
+
res = @regexp.inspect
|
193
|
+
res.gsub!(/\\b/,"")
|
194
|
+
res.gsub!(/i$/,"")
|
195
|
+
return res
|
196
|
+
end
|
197
|
+
|
198
|
+
def to_s
|
199
|
+
s = cleanRegexp + "\n"
|
200
|
+
@list.each { |x| s += " \"" + x + "\"\n" }
|
201
|
+
return s
|
202
|
+
end
|
203
|
+
|
204
|
+
def inspect
|
205
|
+
return cleanRegexp + ": " + @list.inspect
|
206
|
+
end
|
207
|
+
|
208
|
+
end
|
209
|
+
|
210
|
+
|
211
|
+
module Eliza
|
212
|
+
|
213
|
+
# These top level constants define the "application" processed by ELIZA -- the rule
|
214
|
+
# sets used to transform inputs to outputs. The arrays are all initially empty.
|
215
|
+
# The 'load' method reads and parses rules and fills in these arrays. The 'reset'
|
216
|
+
# method empties them.
|
217
|
+
|
218
|
+
@@script = nil
|
219
|
+
@@aliases = Hash.new
|
220
|
+
@@vars = Hash.new
|
221
|
+
@@starts = Array.new
|
222
|
+
@@stops = Array.new
|
223
|
+
@@pre = Hash.new
|
224
|
+
@@post = Hash.new
|
225
|
+
@@default = nil
|
226
|
+
@@rules = Hash.new
|
227
|
+
@@queue = PriorityQueue.new
|
228
|
+
|
229
|
+
@@word = /[a-z\-$']+/i # pattern for a "word" in the input language
|
230
|
+
@@iword = /^[a-z\-$']+/i # same, but must be the first item on the line
|
231
|
+
@@var = /\$\d+/ # variable name in reassembly string
|
232
|
+
|
233
|
+
@@verbose = false
|
234
|
+
|
235
|
+
def Eliza.rules
|
236
|
+
return @@rules
|
237
|
+
end
|
238
|
+
|
239
|
+
def Eliza.queue
|
240
|
+
return @@queue
|
241
|
+
end
|
242
|
+
|
243
|
+
def Eliza.aliases
|
244
|
+
return @@aliases
|
245
|
+
end
|
246
|
+
|
247
|
+
def Eliza.vars
|
248
|
+
return @@vars
|
249
|
+
end
|
250
|
+
|
251
|
+
def Eliza.pre
|
252
|
+
return @@pre
|
253
|
+
end
|
254
|
+
|
255
|
+
def Eliza.post
|
256
|
+
return @@post
|
257
|
+
end
|
258
|
+
|
259
|
+
def Eliza.verbose
|
260
|
+
@@verbose = true
|
261
|
+
end
|
262
|
+
|
263
|
+
def Eliza.quiet
|
264
|
+
@@verbose = false
|
265
|
+
end
|
266
|
+
|
267
|
+
# First pass over the input -- scan each word, apply preprocessing substitutions,
|
268
|
+
# add rule names to the priority queue. NOTE: this method does a destructive
|
269
|
+
# update to the input line....
|
270
|
+
|
271
|
+
def Eliza.scan(line, queue)
|
272
|
+
line.gsub!(@@word) { |w| @@pre.has_key?(w) ? @@pre[w] : w }
|
273
|
+
puts "preprocess: line = '#{line}'" if @@verbose
|
274
|
+
line.scan(@@word) do |w|
|
275
|
+
w.downcase!
|
276
|
+
if r = @@rules[w]
|
277
|
+
queue.insert(r)
|
278
|
+
puts "add rule for '#{w}' to queue" if @@verbose
|
279
|
+
end
|
280
|
+
if (x = @@aliases[w]) && (r = @@rules[x])
|
281
|
+
queue.insert(r)
|
282
|
+
puts "add rule for '#{x}' to queue" if @@verbose
|
283
|
+
end
|
284
|
+
end
|
285
|
+
# queue.each { |r| puts r.key }
|
286
|
+
end
|
287
|
+
|
288
|
+
def Eliza.apply(line, rule)
|
289
|
+
puts "applying rule: key = '#{rule.key}'" if @@verbose
|
290
|
+
if res = rule.apply(line, @@post, @@verbose)
|
291
|
+
if res[0] == ?@
|
292
|
+
rulename = res.slice(1..-1)
|
293
|
+
if @@rules[rulename]
|
294
|
+
return Eliza.apply( line, @@rules[rulename] )
|
295
|
+
else
|
296
|
+
warn "Eliza.apply: no rule for #{rulename}"
|
297
|
+
return nil
|
298
|
+
end
|
299
|
+
else
|
300
|
+
return res
|
301
|
+
end
|
302
|
+
else
|
303
|
+
return nil
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
# The heart of the program -- apply transformation rules to an input sentence.
|
308
|
+
|
309
|
+
def Eliza.transform(s)
|
310
|
+
s.sub!(/[\n\.\?!\-]*$/,"") # strip trailing punctuation
|
311
|
+
s.downcase!
|
312
|
+
|
313
|
+
@@queue = PriorityQueue.new
|
314
|
+
@@queue << @@default # initialize queue with default rule
|
315
|
+
|
316
|
+
Eliza.scan(s, @@queue) # add rules for recognized key words
|
317
|
+
|
318
|
+
while @@queue.length > 0 # apply rules in order of priority
|
319
|
+
p @@queue.collect { |r| r.key } if @@verbose
|
320
|
+
rule = @@queue.shift
|
321
|
+
if result = Eliza.apply(s, rule)
|
322
|
+
return result
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
warn "No rules applied" if @@queue.empty?
|
327
|
+
return nil
|
328
|
+
end
|
329
|
+
|
330
|
+
# The parser calls this method to deal with directives (lines where the first
|
331
|
+
# word begins with a colon)
|
332
|
+
|
333
|
+
def Eliza.parseDirective(line)
|
334
|
+
word = Eliza.detachWord(line)
|
335
|
+
case word
|
336
|
+
when "alias"
|
337
|
+
if line.empty? || line[0] != ?$
|
338
|
+
warn "symbol after :alias must be a variable name; ignoring '#{word} #{line}'"
|
339
|
+
return
|
340
|
+
else
|
341
|
+
sym = Eliza.detachWord(line)
|
342
|
+
@@vars[sym] = Array.new
|
343
|
+
line.split.each do |s|
|
344
|
+
@@aliases[s] = sym
|
345
|
+
@@vars[sym] << s
|
346
|
+
end
|
347
|
+
end
|
348
|
+
when "start"
|
349
|
+
@@starts << line.unquote
|
350
|
+
when "stop"
|
351
|
+
@@stops << line.unquote
|
352
|
+
when "pre"
|
353
|
+
sym = Eliza.detachWord(line)
|
354
|
+
@@pre[sym] = line.unquote
|
355
|
+
when "post"
|
356
|
+
sym = Eliza.detachWord(line)
|
357
|
+
@@post[sym] = line.unquote
|
358
|
+
when "default"
|
359
|
+
@@default = line[@@word]
|
360
|
+
else
|
361
|
+
warn "unknown directive: :#{word} (ignored)"
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
# Remove a word from the front of a line
|
366
|
+
|
367
|
+
def Eliza.detachWord(line)
|
368
|
+
word = line[@@word] # pattern matches the first word
|
369
|
+
if line.index(" ")
|
370
|
+
line.slice!(0..line.index(" ")) # delete up to end of the word
|
371
|
+
line.lstrip! # in case there are extra spaces after word
|
372
|
+
else
|
373
|
+
line.slice!(0..-1) # line just had the one word
|
374
|
+
end
|
375
|
+
return word
|
376
|
+
end
|
377
|
+
|
378
|
+
# Check each pattern's regular expression and replace var names by alternation
|
379
|
+
# constructs. If the script specified a default rule name look up that
|
380
|
+
# rule and save it as the default.
|
381
|
+
|
382
|
+
def Eliza.compileRules
|
383
|
+
@@rules.each do |key,val|
|
384
|
+
a = val.patterns()
|
385
|
+
a.each do |p|
|
386
|
+
expr = p.regexp.inspect
|
387
|
+
expr.gsub!(/\$\w+/) { |x| @@vars[x].join("|") }
|
388
|
+
p.regexp = eval(expr)
|
389
|
+
end
|
390
|
+
end
|
391
|
+
if @@default.class == String
|
392
|
+
@@default = @@rules[@@default]
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
# Parse rules in file f, store them in global arrays. Strategy: use a local
|
397
|
+
# var named 'rule', initially set to nil. New rules start with a single word
|
398
|
+
# at the start of a line. When such a line is found in the input file, create a
|
399
|
+
# new Rule object and store it in 'rule'. Subsequent lines that are part of the
|
400
|
+
# current rule (lines that contain regular expressions or strings) are added to
|
401
|
+
# current Rule object. Directives indicate the end of a rule, so 'rule' is reset
|
402
|
+
# to nil when a directive is seen.
|
403
|
+
|
404
|
+
def Eliza.load(filename)
|
405
|
+
begin
|
406
|
+
Eliza.reset
|
407
|
+
rule = nil
|
408
|
+
File.open(filename).each do |line|
|
409
|
+
line.strip!
|
410
|
+
next if line.empty? || line[0] == ?#
|
411
|
+
if line[0] == ?:
|
412
|
+
Eliza.parseDirective(line)
|
413
|
+
rule = nil
|
414
|
+
else
|
415
|
+
if line =~ @@iword
|
416
|
+
rulename, priority = line.split
|
417
|
+
rule = priority ? Rule.new(rulename, priority.to_i) : Rule.new(rulename)
|
418
|
+
@@rules[rule.key] = rule
|
419
|
+
elsif rule.nil?
|
420
|
+
warn "missing rule name? unexpected input '#{line}'"
|
421
|
+
elsif line[0] == ?/
|
422
|
+
if line[-1] == ?/
|
423
|
+
rule.addPattern(line)
|
424
|
+
else
|
425
|
+
warn "badly formed expression (missing /): '#{line}'"
|
426
|
+
end
|
427
|
+
elsif line[0] == ?"
|
428
|
+
if line[-1] == ?"
|
429
|
+
rule.addReassembly(line.unquote)
|
430
|
+
else
|
431
|
+
warn "badly formed string (missing \"): '#{line}'"
|
432
|
+
end
|
433
|
+
elsif line[0] == ?@
|
434
|
+
rule.addReassembly(line)
|
435
|
+
else
|
436
|
+
warn "unexpected line in rule for #{rulename}: '#{line}'"
|
437
|
+
end
|
438
|
+
end
|
439
|
+
end
|
440
|
+
Eliza.compileRules
|
441
|
+
@@script = filename
|
442
|
+
rescue
|
443
|
+
puts "Error processing #{filename}: #{$!}"
|
444
|
+
return false
|
445
|
+
end
|
446
|
+
return true
|
447
|
+
end
|
448
|
+
|
449
|
+
def Eliza.dump
|
450
|
+
puts "Script: #{@@script}"
|
451
|
+
print "Starts:\n "; p @@starts
|
452
|
+
print "Stops:\n "; p @@stops
|
453
|
+
print "Vars:\n "; p @@vars
|
454
|
+
print "Aliases:\n "; p @@aliases
|
455
|
+
print "Pre:\n "; p @@pre
|
456
|
+
print "Post:\n "; p @@post
|
457
|
+
print "Default:\n "; p @@default
|
458
|
+
print "Queue:\n "; p @@queue.collect { |r| r.key }
|
459
|
+
puts
|
460
|
+
@@rules.each { |key,val| puts val }
|
461
|
+
return nil
|
462
|
+
end
|
463
|
+
|
464
|
+
def Eliza.info
|
465
|
+
puts "Script: #{@@script}"
|
466
|
+
puts "#{@@rules.size} rules"
|
467
|
+
puts "Keys: "
|
468
|
+
|
469
|
+
keys = Array.new
|
470
|
+
@@rules.each_key { |k| keys << k unless k[0] == ?$ }
|
471
|
+
keys += @@aliases.keys
|
472
|
+
puts " " + keys.sort.join(", ")
|
473
|
+
end
|
474
|
+
|
475
|
+
# Initialization -- reset all the aliases, etc, and make a single rule
|
476
|
+
# that echoes the input.
|
477
|
+
|
478
|
+
def Eliza.reset
|
479
|
+
@@script = nil
|
480
|
+
@@aliases.clear
|
481
|
+
@@vars.clear
|
482
|
+
@@starts.clear
|
483
|
+
@@stops.clear
|
484
|
+
@@pre.clear
|
485
|
+
@@post.clear
|
486
|
+
@@rules.clear
|
487
|
+
@@queue.clear
|
488
|
+
|
489
|
+
@@default = Rule.new(:default)
|
490
|
+
@@default.addPattern(/(.*)/)
|
491
|
+
@@default.addReassembly("$1")
|
492
|
+
end
|
493
|
+
|
494
|
+
def Eliza.run
|
495
|
+
puts @@starts[rand(@@starts.length)] if ! @@starts.empty?
|
496
|
+
loop do
|
497
|
+
s = readline(" H: ", true)
|
498
|
+
return if s.nil?
|
499
|
+
s.chomp!
|
500
|
+
next if s.empty?
|
501
|
+
if s == "bye" || s == "quit"
|
502
|
+
puts @@stops[rand(@@stops.length)] if ! @@stops.empty?
|
503
|
+
return
|
504
|
+
end
|
505
|
+
puts " C: " + Eliza.transform(s)
|
506
|
+
end
|
507
|
+
end
|
508
|
+
|
509
|
+
end
|
510
|
+
|
511
|
+
# When invoked from command line load the script specified by the command line
|
512
|
+
# argument and then start ELIZA
|
513
|
+
|
514
|
+
if !defined? IRB
|
515
|
+
filename = ARGV.shift or abort "Usage: eliza.rb F\n Run ELIZA using rules in file F"
|
516
|
+
Eliza.verbose if ARGV[0] == "-v"
|
517
|
+
if Eliza.load(filename)
|
518
|
+
Eliza.run
|
519
|
+
end
|
520
|
+
else
|
521
|
+
Eliza.reset
|
522
|
+
end
|
523
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
=begin rdoc
|
3
|
+
|
4
|
+
== Encryption Lab
|
5
|
+
|
6
|
+
Ruby implementation of Caesar cypher and RSA encryption.
|
7
|
+
|
8
|
+
=end
|
9
|
+
|
10
|
+
module RubyLabs
|
11
|
+
|
12
|
+
module EncryptionLab
|
13
|
+
|
14
|
+
=begin rdoc
|
15
|
+
Caesar cipher -- single letter substitution based on "rotating" each letter +n+ places.
|
16
|
+
=end
|
17
|
+
|
18
|
+
# :begin :caesar
|
19
|
+
def caesar(s, n = 3)
|
20
|
+
res = String.new
|
21
|
+
s.each_byte do |byte|
|
22
|
+
if byte >= ?a && byte <= ?z
|
23
|
+
res << rot(byte, ?a, n)
|
24
|
+
elsif byte >= ?A && byte <= ?Z
|
25
|
+
res << rot(byte, ?A, n)
|
26
|
+
else
|
27
|
+
res << byte
|
28
|
+
end
|
29
|
+
end
|
30
|
+
return res
|
31
|
+
end
|
32
|
+
# :end :caesar
|
33
|
+
|
34
|
+
def rot(char, base, n)
|
35
|
+
return ((char - base) + n) % 26 + base
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
end # EncryptionLab
|
41
|
+
|
42
|
+
end # RubyLabs
|