summaryrefslogtreecommitdiff
path: root/data/rbot/plugins/math.rb
diff options
context:
space:
mode:
authorTom Gilbert <tom@linuxbrit.co.uk>2005-07-27 15:59:13 +0000
committerTom Gilbert <tom@linuxbrit.co.uk>2005-07-27 15:59:13 +0000
commit21949774b91eaec6ecde4eaa8ad121e2c0a36b87 (patch)
tree41a7601e168018ac203bad7ca8d7f9f82515bc28 /data/rbot/plugins/math.rb
parent51cf09ec02d089bfdd80e5f728cfc92a234dc437 (diff)
rearrange repo for packaging
Diffstat (limited to 'data/rbot/plugins/math.rb')
-rw-r--r--data/rbot/plugins/math.rb122
1 files changed, 122 insertions, 0 deletions
diff --git a/data/rbot/plugins/math.rb b/data/rbot/plugins/math.rb
new file mode 100644
index 00000000..4a207389
--- /dev/null
+++ b/data/rbot/plugins/math.rb
@@ -0,0 +1,122 @@
+class MathPlugin < Plugin
+ @@digits = {
+ "first" => "1",
+ "second" => "2",
+ "third" => "3",
+ "fourth" => "4",
+ "fifth" => "5",
+ "sixth" => "6",
+ "seventh" => "7",
+ "eighth" => "8",
+ "ninth" => "9",
+ "tenth" => "10",
+ "one" => "1",
+ "two" => "2",
+ "three" => "3",
+ "four" => "4",
+ "five" => "5",
+ "six" => "6",
+ "seven" => "7",
+ "eight" => "8",
+ "nine" => "9",
+ "ten" => "10"
+ };
+
+ def help(plugin, topic="")
+ "math <expression>, evaluate mathematical expression"
+ end
+ def privmsg(m)
+ unless(m.params)
+ m.reply "incorrect usage: " + help(m.plugin)
+ return
+ end
+
+ expr = m.params.dup
+ @@digits.each {|k,v|
+ expr.gsub!(/\b#{k}\b/, v)
+ }
+
+ while expr =~ /(exp ([\w\d]+))/
+ exp = $1
+ val = Math.exp($2).to_s
+ expr.gsub!(/#{Regexp.escape exp}/, "+#{val}")
+ end
+
+ while expr =~ /^\s*(dec2hex\s*(\d+))\s*\?*/
+ exp = $1
+ val = sprintf("%x", $2)
+ expr.gsub!(/#{Regexp.escape exp}/, "+#{val}")
+ end
+
+ expr.gsub(/\be\b/, Math.exp(1).to_s)
+
+ while expr =~ /(log\s*((\d+\.?\d*)|\d*\.?\d+))\s*/
+ exp = $1
+ res = $2
+
+ if res == 0
+ val = "Infinity"
+ else
+ val = Math.log(res).to_s
+ end
+
+ expr.gsub!(/#{Regexp.escape exp}/, "+#{val}")
+ end
+
+ while expr =~ /(bin2dec ([01]+))/
+ exp = $1
+ val = join('', unpack('B*', pack('N', $2)))
+ val.gsub!(/^0+/, "")
+ expr.gsub!(/#{Regexp.escape exp}/, "+#{val}")
+ end
+
+ expr.gsub!(/ to the power of /, " ** ")
+ expr.gsub!(/ to the /, " ** ")
+ expr.gsub!(/\btimes\b/, "*")
+ expr.gsub!(/\bdiv(ided by)? /, "/ ")
+ expr.gsub!(/\bover /, "/ ")
+ expr.gsub!(/\bsquared/, "**2 ")
+ expr.gsub!(/\bcubed/, "**3 ")
+ expr.gsub!(/\bto\s+(\d+)(r?st|nd|rd|th)?( power)?/, "**\1 ")
+ expr.gsub!(/\bpercent of/, "*0.01*")
+ expr.gsub!(/\bpercent/, "*0.01")
+ expr.gsub!(/\% of\b/, "*0.01*")
+ expr.gsub!(/\%/, "*0.01")
+ expr.gsub!(/\bsquare root of (\d+)/, "\1 ** 0.5 ")
+ expr.gsub!(/\bcubed? root of (\d+)/, "\1 **(1.0/3.0) ")
+ expr.gsub!(/ of /, " * ")
+ expr.gsub!(/(bit(-| )?)?xor(\'?e?d( with))?/, "^")
+ expr.gsub!(/(bit(-| )?)?or(\'?e?d( with))?/, "|")
+ expr.gsub!(/bit(-| )?and(\'?e?d( with))?/, "& ")
+ expr.gsub!(/(plus|and)/, "+")
+
+ if (expr =~ /^\s*[-\d*+\s()\/^\.\|\&\*\!]+\s*$/ &&
+ expr !~ /^\s*\(?\d+\.?\d*\)?\s*$/ &&
+ expr !~ /^\s*$/ &&
+ expr !~ /^\s*[( )]+\s*$/)
+
+ begin
+ debug "evaluating expression \"#{expr}\""
+ answer = eval(expr)
+ if answer =~ /^[-+\de\.]+$/
+ answer = sprintf("%1.12f", answer)
+ answer.gsub!(/\.?0+$/, "")
+ answer.gsub!(/(\.\d+)000\d+/, '\1')
+ if (answer.length > 30)
+ answer = "a number with >30 digits..."
+ end
+ end
+ m.reply answer
+ rescue Exception => e
+ puts "couldn't evaluate expression \"#{m.params}\": #{e}"
+ m.reply "illegal expression \"#{m.params}\""
+ return
+ end
+ else
+ m.reply "illegal expression \"#{m.params}\""
+ return
+ end
+ end
+end
+plugin = MathPlugin.new
+plugin.register("math")